blob: 01af14b71eb358ef67bc742624ab75a21e12a295 [file] [log] [blame]
developer29c4d2d2022-12-26 19:41:22 +08001From e16f200dc1d2f69efc78c7c55af0d7b410a981f9 Mon Sep 17 00:00:00 2001
2From: Glenn Strauss <gstrauss@gluelogic.com>
3Date: Tue, 5 Jul 2022 02:49:50 -0400
4Subject: [PATCH 1/7] mbedtls: TLS/crypto option (initial port)
5
6Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
7---
8 hostapd/Makefile | 91 +
9 hostapd/defconfig | 15 +-
10 src/crypto/crypto_mbedtls.c | 4043 +++++++++++++++++
11 src/crypto/tls_mbedtls.c | 3313 ++++++++++++++
12 .../build/build-wpa_supplicant-mbedtls.config | 24 +
13 tests/hwsim/example-hostapd.config | 4 +
14 tests/hwsim/example-wpa_supplicant.config | 4 +
15 wpa_supplicant/Makefile | 74 +
16 wpa_supplicant/defconfig | 6 +-
17 9 files changed, 7571 insertions(+), 3 deletions(-)
18 create mode 100644 src/crypto/crypto_mbedtls.c
19 create mode 100644 src/crypto/tls_mbedtls.c
20 create mode 100644 tests/build/build-wpa_supplicant-mbedtls.config
21
22--- a/hostapd/Makefile
23+++ b/hostapd/Makefile
24@@ -745,6 +745,40 @@ endif
25 CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\"
26 endif
27
28+ifeq ($(CONFIG_TLS), mbedtls)
29+ifndef CONFIG_CRYPTO
30+CONFIG_CRYPTO=mbedtls
31+endif
32+ifdef TLS_FUNCS
33+OBJS += ../src/crypto/tls_mbedtls.o
34+LIBS += -lmbedtls
35+ifndef CONFIG_DPP
36+LIBS += -lmbedx509
37+endif
38+endif
39+OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
40+HOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
41+SOBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
42+ifdef NEED_FIPS186_2_PRF
43+OBJS += ../src/crypto/fips_prf_internal.o
44+SHA1OBJS += ../src/crypto/sha1-internal.o
45+endif
46+ifeq ($(CONFIG_CRYPTO), mbedtls)
47+ifdef CONFIG_DPP
48+LIBS += -lmbedx509
49+LIBS_h += -lmbedx509
50+LIBS_n += -lmbedx509
51+LIBS_s += -lmbedx509
52+endif
53+LIBS += -lmbedcrypto
54+LIBS_h += -lmbedcrypto
55+LIBS_n += -lmbedcrypto
56+LIBS_s += -lmbedcrypto
57+# XXX: create a config option?
58+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
59+endif
60+endif
61+
62 ifeq ($(CONFIG_TLS), gnutls)
63 ifndef CONFIG_CRYPTO
64 # default to libgcrypt
65@@ -924,9 +958,11 @@ endif
66
67 ifneq ($(CONFIG_TLS), openssl)
68 ifneq ($(CONFIG_TLS), wolfssl)
69+ifneq ($(CONFIG_TLS), mbedtls)
70 AESOBJS += ../src/crypto/aes-wrap.o
71 endif
72 endif
73+endif
74 ifdef NEED_AES_EAX
75 AESOBJS += ../src/crypto/aes-eax.o
76 NEED_AES_CTR=y
77@@ -936,38 +972,48 @@ AESOBJS += ../src/crypto/aes-siv.o
78 NEED_AES_CTR=y
79 endif
80 ifdef NEED_AES_CTR
81+ifneq ($(CONFIG_TLS), mbedtls)
82 AESOBJS += ../src/crypto/aes-ctr.o
83 endif
84+endif
85 ifdef NEED_AES_ENCBLOCK
86+ifneq ($(CONFIG_TLS), mbedtls)
87 AESOBJS += ../src/crypto/aes-encblock.o
88 endif
89+endif
90 ifneq ($(CONFIG_TLS), openssl)
91 ifneq ($(CONFIG_TLS), linux)
92 ifneq ($(CONFIG_TLS), wolfssl)
93+ifneq ($(CONFIG_TLS), mbedtls)
94 AESOBJS += ../src/crypto/aes-omac1.o
95 endif
96 endif
97 endif
98+endif
99 ifdef NEED_AES_UNWRAP
100 ifneq ($(CONFIG_TLS), openssl)
101 ifneq ($(CONFIG_TLS), linux)
102 ifneq ($(CONFIG_TLS), wolfssl)
103+ifneq ($(CONFIG_TLS), mbedtls)
104 NEED_AES_DEC=y
105 AESOBJS += ../src/crypto/aes-unwrap.o
106 endif
107 endif
108 endif
109 endif
110+endif
111 ifdef NEED_AES_CBC
112 NEED_AES_DEC=y
113 ifneq ($(CONFIG_TLS), openssl)
114 ifneq ($(CONFIG_TLS), linux)
115 ifneq ($(CONFIG_TLS), wolfssl)
116+ifneq ($(CONFIG_TLS), mbedtls)
117 AESOBJS += ../src/crypto/aes-cbc.o
118 endif
119 endif
120 endif
121 endif
122+endif
123 ifdef NEED_AES_DEC
124 ifdef CONFIG_INTERNAL_AES
125 AESOBJS += ../src/crypto/aes-internal-dec.o
126@@ -982,12 +1028,16 @@ ifneq ($(CONFIG_TLS), openssl)
127 ifneq ($(CONFIG_TLS), linux)
128 ifneq ($(CONFIG_TLS), gnutls)
129 ifneq ($(CONFIG_TLS), wolfssl)
130+ifneq ($(CONFIG_TLS), mbedtls)
131 SHA1OBJS += ../src/crypto/sha1.o
132 endif
133 endif
134 endif
135 endif
136+endif
137+ifneq ($(CONFIG_TLS), mbedtls)
138 SHA1OBJS += ../src/crypto/sha1-prf.o
139+endif
140 ifdef CONFIG_INTERNAL_SHA1
141 SHA1OBJS += ../src/crypto/sha1-internal.o
142 ifdef NEED_FIPS186_2_PRF
143@@ -996,16 +1046,22 @@ endif
144 endif
145 ifneq ($(CONFIG_TLS), openssl)
146 ifneq ($(CONFIG_TLS), wolfssl)
147+ifneq ($(CONFIG_TLS), mbedtls)
148 SHA1OBJS += ../src/crypto/sha1-pbkdf2.o
149 endif
150 endif
151+endif
152 ifdef NEED_T_PRF
153+ifneq ($(CONFIG_TLS), mbedtls)
154 SHA1OBJS += ../src/crypto/sha1-tprf.o
155 endif
156+endif
157 ifdef NEED_TLS_PRF
158+ifneq ($(CONFIG_TLS), mbedtls)
159 SHA1OBJS += ../src/crypto/sha1-tlsprf.o
160 endif
161 endif
162+endif
163
164 ifdef NEED_SHA1
165 OBJS += $(SHA1OBJS)
166@@ -1015,11 +1071,13 @@ ifneq ($(CONFIG_TLS), openssl)
167 ifneq ($(CONFIG_TLS), linux)
168 ifneq ($(CONFIG_TLS), gnutls)
169 ifneq ($(CONFIG_TLS), wolfssl)
170+ifneq ($(CONFIG_TLS), mbedtls)
171 OBJS += ../src/crypto/md5.o
172 endif
173 endif
174 endif
175 endif
176+endif
177
178 ifdef NEED_MD5
179 ifdef CONFIG_INTERNAL_MD5
180@@ -1058,56 +1116,81 @@ ifneq ($(CONFIG_TLS), openssl)
181 ifneq ($(CONFIG_TLS), linux)
182 ifneq ($(CONFIG_TLS), gnutls)
183 ifneq ($(CONFIG_TLS), wolfssl)
184+ifneq ($(CONFIG_TLS), mbedtls)
185 OBJS += ../src/crypto/sha256.o
186 endif
187 endif
188 endif
189 endif
190+endif
191+ifneq ($(CONFIG_TLS), mbedtls)
192 OBJS += ../src/crypto/sha256-prf.o
193+endif
194 ifdef CONFIG_INTERNAL_SHA256
195 OBJS += ../src/crypto/sha256-internal.o
196 endif
197 ifdef NEED_TLS_PRF_SHA256
198+ifneq ($(CONFIG_TLS), mbedtls)
199 OBJS += ../src/crypto/sha256-tlsprf.o
200 endif
201+endif
202 ifdef NEED_TLS_PRF_SHA384
203+ifneq ($(CONFIG_TLS), mbedtls)
204 OBJS += ../src/crypto/sha384-tlsprf.o
205 endif
206+endif
207 ifdef NEED_HMAC_SHA256_KDF
208+CFLAGS += -DCONFIG_HMAC_SHA256_KDF
209+ifneq ($(CONFIG_TLS), mbedtls)
210 OBJS += ../src/crypto/sha256-kdf.o
211 endif
212+endif
213 ifdef NEED_HMAC_SHA384_KDF
214+CFLAGS += -DCONFIG_HMAC_SHA384_KDF
215+ifneq ($(CONFIG_TLS), mbedtls)
216 OBJS += ../src/crypto/sha384-kdf.o
217 endif
218+endif
219 ifdef NEED_HMAC_SHA512_KDF
220+CFLAGS += -DCONFIG_HMAC_SHA512_KDF
221+ifneq ($(CONFIG_TLS), mbedtls)
222 OBJS += ../src/crypto/sha512-kdf.o
223 endif
224+endif
225 ifdef NEED_SHA384
226 CFLAGS += -DCONFIG_SHA384
227 ifneq ($(CONFIG_TLS), openssl)
228 ifneq ($(CONFIG_TLS), linux)
229 ifneq ($(CONFIG_TLS), gnutls)
230 ifneq ($(CONFIG_TLS), wolfssl)
231+ifneq ($(CONFIG_TLS), mbedtls)
232 OBJS += ../src/crypto/sha384.o
233 endif
234 endif
235 endif
236 endif
237+endif
238+ifneq ($(CONFIG_TLS), mbedtls)
239 OBJS += ../src/crypto/sha384-prf.o
240 endif
241+endif
242 ifdef NEED_SHA512
243 CFLAGS += -DCONFIG_SHA512
244 ifneq ($(CONFIG_TLS), openssl)
245 ifneq ($(CONFIG_TLS), linux)
246 ifneq ($(CONFIG_TLS), gnutls)
247 ifneq ($(CONFIG_TLS), wolfssl)
248+ifneq ($(CONFIG_TLS), mbedtls)
249 OBJS += ../src/crypto/sha512.o
250 endif
251 endif
252 endif
253 endif
254+endif
255+ifneq ($(CONFIG_TLS), mbedtls)
256 OBJS += ../src/crypto/sha512-prf.o
257 endif
258+endif
259
260 ifdef CONFIG_INTERNAL_SHA384
261 CFLAGS += -DCONFIG_INTERNAL_SHA384
262@@ -1152,11 +1235,13 @@ HOBJS += $(SHA1OBJS)
263 ifneq ($(CONFIG_TLS), openssl)
264 ifneq ($(CONFIG_TLS), linux)
265 ifneq ($(CONFIG_TLS), wolfssl)
266+ifneq ($(CONFIG_TLS), mbedtls)
267 HOBJS += ../src/crypto/md5.o
268 endif
269 endif
270 endif
271 endif
272+endif
273
274 ifdef CONFIG_RADIUS_SERVER
275 CFLAGS += -DRADIUS_SERVER
276@@ -1327,7 +1412,9 @@ NOBJS += ../src/utils/trace.o
277 endif
278
279 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
280+ifneq ($(CONFIG_TLS), mbedtls)
281 HOBJS += ../src/crypto/aes-encblock.o
282+endif
283 ifdef CONFIG_INTERNAL_AES
284 HOBJS += ../src/crypto/aes-internal.o
285 HOBJS += ../src/crypto/aes-internal-enc.o
286@@ -1350,13 +1437,17 @@ SOBJS += ../src/common/sae.o
287 SOBJS += ../src/common/sae_pk.o
288 SOBJS += ../src/common/dragonfly.o
289 SOBJS += $(AESOBJS)
290+ifneq ($(CONFIG_TLS), mbedtls)
291 SOBJS += ../src/crypto/sha256-prf.o
292 SOBJS += ../src/crypto/sha384-prf.o
293 SOBJS += ../src/crypto/sha512-prf.o
294+endif
295 SOBJS += ../src/crypto/dh_groups.o
296+ifneq ($(CONFIG_TLS), mbedtls)
297 SOBJS += ../src/crypto/sha256-kdf.o
298 SOBJS += ../src/crypto/sha384-kdf.o
299 SOBJS += ../src/crypto/sha512-kdf.o
300+endif
301
302 _OBJS_VAR := NOBJS
303 include ../src/objs.mk
304--- a/hostapd/defconfig
305+++ b/hostapd/defconfig
306@@ -6,9 +6,21 @@
307 # just setting VARIABLE=n is not disabling that variable.
308 #
309 # This file is included in Makefile, so variables like CFLAGS and LIBS can also
310-# be modified from here. In most cass, these lines should use += in order not
311+# be modified from here. In most cases, these lines should use += in order not
312 # to override previous values of the variables.
313
314+
315+# Uncomment following two lines and fix the paths if you have installed TLS
316+# libraries in a non-default location
317+#CFLAGS += -I/usr/local/openssl/include
318+#LIBS += -L/usr/local/openssl/lib
319+
320+# Some Red Hat versions seem to include kerberos header files from OpenSSL, but
321+# the kerberos files are not in the default include path. Following line can be
322+# used to fix build issues on such systems (krb5.h not found).
323+#CFLAGS += -I/usr/include/kerberos
324+
325+
326 # Driver interface for Host AP driver
327 CONFIG_DRIVER_HOSTAP=y
328
329@@ -278,6 +290,7 @@ CONFIG_IPV6=y
330 # openssl = OpenSSL (default)
331 # gnutls = GnuTLS
332 # internal = Internal TLSv1 implementation (experimental)
333+# mbedtls = mbed TLS
334 # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
335 # none = Empty template
336 #CONFIG_TLS=openssl
337--- /dev/null
338+++ b/src/crypto/crypto_mbedtls.c
339@@ -0,0 +1,4043 @@
340+/*
341+ * crypto wrapper functions for mbed TLS
342+ *
343+ * SPDX-FileCopyrightText: 2022 Glenn Strauss <gstrauss@gluelogic.com>
344+ * SPDX-License-Identifier: BSD-3-Clause
345+ */
346+
347+#include "utils/includes.h"
348+#include "utils/common.h"
349+
350+#include <mbedtls/version.h>
351+#include <mbedtls/entropy.h>
352+#include <mbedtls/ctr_drbg.h>
353+#include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */
354+#include <mbedtls/asn1.h>
355+#include <mbedtls/asn1write.h>
356+#include <mbedtls/aes.h>
357+#include <mbedtls/md.h>
358+#include <mbedtls/md5.h>
359+#include <mbedtls/sha1.h>
360+#include <mbedtls/sha256.h>
361+#include <mbedtls/sha512.h>
362+
363+#ifndef MBEDTLS_PRIVATE
364+#define MBEDTLS_PRIVATE(x) x
365+#endif
366+
367+/* hostapd/wpa_supplicant provides forced_memzero(),
368+ * but prefer mbedtls_platform_zeroize() */
369+#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz)
370+
371+#ifndef __has_attribute
372+#define __has_attribute(x) 0
373+#endif
374+
375+#ifndef __GNUC_PREREQ
376+#define __GNUC_PREREQ(maj,min) 0
377+#endif
378+
379+#ifndef __attribute_cold__
380+#if __has_attribute(cold) \
381+ || __GNUC_PREREQ(4,3)
382+#define __attribute_cold__ __attribute__((__cold__))
383+#else
384+#define __attribute_cold__
385+#endif
386+#endif
387+
388+#ifndef __attribute_noinline__
389+#if __has_attribute(noinline) \
390+ || __GNUC_PREREQ(3,1)
391+#define __attribute_noinline__ __attribute__((__noinline__))
392+#else
393+#define __attribute_noinline__
394+#endif
395+#endif
396+
397+#include "crypto.h"
398+#include "aes_wrap.h"
399+#include "aes.h"
400+#include "md5.h"
401+#include "sha1.h"
402+#include "sha256.h"
403+#include "sha384.h"
404+#include "sha512.h"
405+
406+
407+/*
408+ * selective code inclusion based on preprocessor defines
409+ *
410+ * future: additional code could be wrapped with preprocessor checks if
411+ * wpa_supplicant/Makefile and hostap/Makefile were more consistent with
412+ * setting preprocessor defines for named groups of functionality
413+ */
414+
415+#if defined(CONFIG_FIPS)
416+#undef MBEDTLS_MD4_C /* omit md4_vector() */
417+#undef MBEDTLS_MD5_C /* omit md5_vector() hmac_md5_vector() hmac_md5() */
418+#undef MBEDTLS_DES_C /* omit des_encrypt() */
419+#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */
420+#define CRYPTO_MBEDTLS_CONFIG_FIPS
421+#endif
422+
423+#if !defined(CONFIG_FIPS)
424+#if defined(EAP_PWD) \
425+ || defined(EAP_LEAP) || defined(EAP_LEAP_DYNAMIC) \
426+ || defined(EAP_TTLS) || defined(EAP_TTLS_DYNAMIC) \
427+ || defined(EAP_MSCHAPv2) || defined(EAP_MSCHAPv2_DYNAMIC) \
428+ || defined(EAP_SERVER_MSCHAPV2)
429+#ifndef MBEDTLS_MD4_C /* (MD4 not in mbedtls 3.x) */
430+#include "md4-internal.c"/* pull in hostap local implementation */
431+#endif /* md4_vector() */
432+#else
433+#undef MBEDTLS_MD4_C /* omit md4_vector() */
434+#endif
435+#endif
436+
437+#if !defined(CONFIG_NO_RC4) && !defined(CONFIG_NO_WPA)
438+#ifndef MBEDTLS_ARC4_C /* (RC4 not in mbedtls 3.x) */
439+#include "rc4.c" /* pull in hostap local implementation */
440+#endif /* rc4_skip() */
441+#else
442+#undef MBEDTLS_ARC4_C /* omit rc4_skip() */
443+#endif
444+
445+#if defined(CONFIG_MACSEC) \
446+ || defined(CONFIG_NO_RADIUS) \
447+ || defined(CONFIG_IEEE80211R) \
448+ || defined(EAP_SERVER_FAST) \
449+ || defined(EAP_SERVER_TEAP) \
450+ || !defined(CONFIG_NO_WPA)
451+ /* aes_wrap() aes_unwrap() */
452+#else
453+#undef MBEDTLS_NIST_KW_C /* omit aes_wrap() aes_unwrap() */
454+#endif
455+
456+#if !defined(CONFIG_SHA256)
457+#undef MBEDTLS_SHA256_C
458+#endif
459+
460+#if !defined(CONFIG_SHA384) && !defined(CONFIG_SHA512)
461+#undef MBEDTLS_SHA512_C
462+#endif
463+
464+#if defined(CONFIG_HMAC_SHA256_KDF)
465+#define CRYPTO_MBEDTLS_HMAC_KDF_SHA256
466+#endif
467+#if defined(CONFIG_HMAC_SHA384_KDF)
468+#define CRYPTO_MBEDTLS_HMAC_KDF_SHA384
469+#endif
470+#if defined(CONFIG_HMAC_SHA512_KDF)
471+#define CRYPTO_MBEDTLS_HMAC_KDF_SHA512
472+#endif
473+
474+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \
475+ || defined(EAP_TEAP) || defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST)
476+#define CRYPTO_MBEDTLS_SHA1_T_PRF
477+#endif
478+
479+#if defined(CONFIG_DES)
480+#define CRYPTO_MBEDTLS_DES_ENCRYPT
481+#endif /* des_encrypt() */
482+
483+#if !defined(CONFIG_NO_PBKDF2)
484+#define CRYPTO_MBEDTLS_PBKDF2_SHA1
485+#endif /* pbkdf2_sha1() */
486+
487+#if defined(EAP_IKEV2) \
488+ || defined(EAP_IKEV2_DYNAMIC) \
489+ || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */
490+#define CRYPTO_MBEDTLS_CRYPTO_CIPHER
491+#endif /* crypto_cipher_*() */
492+
493+#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */
494+#define CRYPTO_MBEDTLS_CRYPTO_HASH
495+#endif /* crypto_hash_*() */
496+
497+#if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ \
498+ || defined(CONFIG_SAE) /* CONFIG_SAE=y */
499+#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM
500+#endif /* crypto_bignum_*() */
501+
502+#if defined(EAP_PWD) /* CONFIG_EAP_PWD=y */ \
503+ || defined(EAP_EKE) /* CONFIG_EAP_EKE=y */ \
504+ || defined(EAP_EKE_DYNAMIC) /* CONFIG_EAP_EKE=y */ \
505+ || defined(EAP_SERVER_EKE) /* CONFIG_EAP_EKE=y */ \
506+ || defined(EAP_IKEV2) /* CONFIG_EAP_IKEV2y */ \
507+ || defined(EAP_IKEV2_DYNAMIC)/* CONFIG_EAP_IKEV2=y */ \
508+ || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ \
509+ || defined(CONFIG_SAE) /* CONFIG_SAE=y */ \
510+ || defined(CONFIG_WPS) /* CONFIG_WPS=y */
511+#define CRYPTO_MBEDTLS_CRYPTO_DH
512+#if defined(CONFIG_WPS_NFC)
513+#define CRYPTO_MBEDTLS_DH5_INIT_FIXED
514+#endif /* dh5_init_fixed() */
515+#endif /* crypto_dh_*() */
516+
517+#if !defined(CONFIG_NO_WPA) /* CONFIG_NO_WPA= */
518+#define CRYPTO_MBEDTLS_CRYPTO_ECDH
519+#endif /* crypto_ecdh_*() */
520+
521+#if defined(CONFIG_ECC)
522+#define CRYPTO_MBEDTLS_CRYPTO_BIGNUM
523+#define CRYPTO_MBEDTLS_CRYPTO_EC
524+#endif /* crypto_ec_*() crypto_ec_key_*() */
525+
526+#if defined(CONFIG_DPP) /* CONFIG_DPP=y */
527+#define CRYPTO_MBEDTLS_CRYPTO_EC_DPP /* extra for DPP */
528+#define CRYPTO_MBEDTLS_CRYPTO_CSR
529+#endif /* crypto_csr_*() */
530+
531+#if defined(CONFIG_DPP3) /* CONFIG_DPP3=y */
532+#define CRYPTO_MBEDTLS_CRYPTO_HPKE
533+#endif
534+
535+#if defined(CONFIG_DPP2) /* CONFIG_DPP2=y */
536+#define CRYPTO_MBEDTLS_CRYPTO_PKCS7
537+#endif /* crypto_pkcs7_*() */
538+
539+#if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) \
540+ || defined(EAP_AKA) || defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) \
541+ || defined(CONFIG_AP) || defined(HOSTAPD)
542+/* CONFIG_EAP_SIM=y CONFIG_EAP_AKA=y CONFIG_AP=y HOSTAPD */
543+#if defined(CRYPTO_RSA_OAEP_SHA256)
544+#define CRYPTO_MBEDTLS_CRYPTO_RSA
545+#endif
546+#endif /* crypto_rsa_*() */
547+
548+
549+static int ctr_drbg_init_state;
550+static mbedtls_ctr_drbg_context ctr_drbg;
551+static mbedtls_entropy_context entropy;
552+
553+#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM
554+#include <mbedtls/bignum.h>
555+static mbedtls_mpi mpi_sw_A;
556+#endif
557+
558+__attribute_cold__
559+__attribute_noinline__
560+static mbedtls_ctr_drbg_context * ctr_drbg_init(void)
561+{
562+ mbedtls_ctr_drbg_init(&ctr_drbg);
563+ mbedtls_entropy_init(&entropy);
564+ if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
565+ NULL, 0)) {
566+ wpa_printf(MSG_ERROR, "Init of random number generator failed");
567+ /* XXX: abort? */
568+ }
569+ else
570+ ctr_drbg_init_state = 1;
571+
572+ return &ctr_drbg;
573+}
574+
575+__attribute_cold__
576+void crypto_unload(void)
577+{
578+ if (ctr_drbg_init_state) {
579+ mbedtls_ctr_drbg_free(&ctr_drbg);
580+ mbedtls_entropy_free(&entropy);
581+ #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM
582+ mbedtls_mpi_free(&mpi_sw_A);
583+ #endif
584+ ctr_drbg_init_state = 0;
585+ }
586+}
587+
588+/* init ctr_drbg on first use
589+ * crypto_global_init() and crypto_global_deinit() are not available here
590+ * (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */
591+mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/
592+inline
593+mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void)
594+{
595+ return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init();
596+}
597+
598+#ifdef CRYPTO_MBEDTLS_CONFIG_FIPS
599+int crypto_get_random(void *buf, size_t len)
600+{
601+ return mbedtls_ctr_drbg_random(crypto_mbedtls_ctr_drbg(),buf,len) ? -1 : 0;
602+}
603+#endif
604+
605+
606+#if 1
607+
608+/* tradeoff: slightly smaller code size here at cost of slight increase
609+ * in instructions and function calls at runtime versus the expanded
610+ * per-message-digest code that follows in #else (~0.5 kib .text larger) */
611+
612+__attribute_noinline__
613+static int md_vector(size_t num_elem, const u8 *addr[], const size_t *len,
614+ u8 *mac, mbedtls_md_type_t md_type)
615+{
616+ mbedtls_md_context_t ctx;
617+ mbedtls_md_init(&ctx);
618+ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0){
619+ mbedtls_md_free(&ctx);
620+ return -1;
621+ }
622+ mbedtls_md_starts(&ctx);
623+ for (size_t i = 0; i < num_elem; ++i)
624+ mbedtls_md_update(&ctx, addr[i], len[i]);
625+ mbedtls_md_finish(&ctx, mac);
626+ mbedtls_md_free(&ctx);
627+ return 0;
628+}
629+
630+#ifdef MBEDTLS_SHA512_C
631+int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
632+{
633+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA512);
634+}
635+
636+int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
637+{
638+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA384);
639+}
640+#endif
641+
642+#ifdef MBEDTLS_SHA256_C
643+int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
644+{
645+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA256);
646+}
647+#endif
648+
649+#ifdef MBEDTLS_SHA1_C
650+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
651+{
652+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA1);
653+}
654+#endif
655+
656+#ifdef MBEDTLS_MD5_C
657+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
658+{
659+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD5);
660+}
661+#endif
662+
663+#ifdef MBEDTLS_MD4_C
664+#include <mbedtls/md4.h>
665+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
666+{
667+ return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD4);
668+}
669+#endif
670+
671+#else /* expanded per-message-digest functions */
672+
673+#ifdef MBEDTLS_SHA512_C
674+#include <mbedtls/sha512.h>
675+__attribute_noinline__
676+static int sha384_512_vector(size_t num_elem, const u8 *addr[],
677+ const size_t *len, u8 *mac, int is384)
678+{
679+ struct mbedtls_sha512_context ctx;
680+ mbedtls_sha512_init(&ctx);
681+ #if MBEDTLS_VERSION_MAJOR >= 3
682+ mbedtls_sha512_starts(&ctx, is384);
683+ for (size_t i = 0; i < num_elem; ++i)
684+ mbedtls_sha512_update(&ctx, addr[i], len[i]);
685+ mbedtls_sha512_finish(&ctx, mac);
686+ #else
687+ mbedtls_sha512_starts_ret(&ctx, is384);
688+ for (size_t i = 0; i < num_elem; ++i)
689+ mbedtls_sha512_update_ret(&ctx, addr[i], len[i]);
690+ mbedtls_sha512_finish_ret(&ctx, mac);
691+ #endif
692+ mbedtls_sha512_free(&ctx);
693+ return 0;
694+}
695+
696+int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
697+{
698+ return sha384_512_vector(num_elem, addr, len, mac, 0);
699+}
700+
701+int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
702+{
703+ return sha384_512_vector(num_elem, addr, len, mac, 1);
704+}
705+#endif
706+
707+#ifdef MBEDTLS_SHA256_C
708+#include <mbedtls/sha256.h>
709+int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
710+{
711+ struct mbedtls_sha256_context ctx;
712+ mbedtls_sha256_init(&ctx);
713+ #if MBEDTLS_VERSION_MAJOR >= 3
714+ mbedtls_sha256_starts(&ctx, 0);
715+ for (size_t i = 0; i < num_elem; ++i)
716+ mbedtls_sha256_update(&ctx, addr[i], len[i]);
717+ mbedtls_sha256_finish(&ctx, mac);
718+ #else
719+ mbedtls_sha256_starts_ret(&ctx, 0);
720+ for (size_t i = 0; i < num_elem; ++i)
721+ mbedtls_sha256_update_ret(&ctx, addr[i], len[i]);
722+ mbedtls_sha256_finish_ret(&ctx, mac);
723+ #endif
724+ mbedtls_sha256_free(&ctx);
725+ return 0;
726+}
727+#endif
728+
729+#ifdef MBEDTLS_SHA1_C
730+#include <mbedtls/sha1.h>
731+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
732+{
733+ struct mbedtls_sha1_context ctx;
734+ mbedtls_sha1_init(&ctx);
735+ #if MBEDTLS_VERSION_MAJOR >= 3
736+ mbedtls_sha1_starts(&ctx);
737+ for (size_t i = 0; i < num_elem; ++i)
738+ mbedtls_sha1_update(&ctx, addr[i], len[i]);
739+ mbedtls_sha1_finish(&ctx, mac);
740+ #else
741+ mbedtls_sha1_starts_ret(&ctx);
742+ for (size_t i = 0; i < num_elem; ++i)
743+ mbedtls_sha1_update_ret(&ctx, addr[i], len[i]);
744+ mbedtls_sha1_finish_ret(&ctx, mac);
745+ #endif
746+ mbedtls_sha1_free(&ctx);
747+ return 0;
748+}
749+#endif
750+
751+#ifdef MBEDTLS_MD5_C
752+#include <mbedtls/md5.h>
753+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
754+{
755+ struct mbedtls_md5_context ctx;
756+ mbedtls_md5_init(&ctx);
757+ #if MBEDTLS_VERSION_MAJOR >= 3
758+ mbedtls_md5_starts(&ctx);
759+ for (size_t i = 0; i < num_elem; ++i)
760+ mbedtls_md5_update(&ctx, addr[i], len[i]);
761+ mbedtls_md5_finish(&ctx, mac);
762+ #else
763+ mbedtls_md5_starts_ret(&ctx);
764+ for (size_t i = 0; i < num_elem; ++i)
765+ mbedtls_md5_update_ret(&ctx, addr[i], len[i]);
766+ mbedtls_md5_finish_ret(&ctx, mac);
767+ #endif
768+ mbedtls_md5_free(&ctx);
769+ return 0;
770+}
771+#endif
772+
773+#ifdef MBEDTLS_MD4_C
774+#include <mbedtls/md4.h>
775+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
776+{
777+ struct mbedtls_md4_context ctx;
778+ mbedtls_md4_init(&ctx);
779+ mbedtls_md4_starts_ret(&ctx);
780+ for (size_t i = 0; i < num_elem; ++i)
781+ mbedtls_md4_update_ret(&ctx, addr[i], len[i]);
782+ mbedtls_md4_finish_ret(&ctx, mac);
783+ mbedtls_md4_free(&ctx);
784+ return 0;
785+}
786+#endif
787+
788+#endif /* expanded per-message-digest functions */
789+
790+
791+__attribute_noinline__
792+static int hmac_vector(const u8 *key, size_t key_len, size_t num_elem,
793+ const u8 *addr[], const size_t *len, u8 *mac,
794+ mbedtls_md_type_t md_type)
795+{
796+ mbedtls_md_context_t ctx;
797+ mbedtls_md_init(&ctx);
798+ if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0){
799+ mbedtls_md_free(&ctx);
800+ return -1;
801+ }
802+ mbedtls_md_hmac_starts(&ctx, key, key_len);
803+ for (size_t i = 0; i < num_elem; ++i)
804+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
805+ mbedtls_md_hmac_finish(&ctx, mac);
806+ mbedtls_md_free(&ctx);
807+ return 0;
808+}
809+
810+#ifdef MBEDTLS_SHA512_C
811+int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
812+ const u8 *addr[], const size_t *len, u8 *mac)
813+{
814+ return hmac_vector(key, key_len, num_elem, addr, len, mac,
815+ MBEDTLS_MD_SHA512);
816+}
817+
818+int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
819+ u8 *mac)
820+{
821+ return hmac_vector(key, key_len, 1, &data, &data_len, mac,
822+ MBEDTLS_MD_SHA512);
823+}
824+
825+int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
826+ const u8 *addr[], const size_t *len, u8 *mac)
827+{
828+ return hmac_vector(key, key_len, num_elem, addr, len, mac,
829+ MBEDTLS_MD_SHA384);
830+}
831+
832+int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
833+ u8 *mac)
834+{
835+ return hmac_vector(key, key_len, 1, &data, &data_len, mac,
836+ MBEDTLS_MD_SHA384);
837+}
838+#endif
839+
840+#ifdef MBEDTLS_SHA256_C
841+int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
842+ const u8 *addr[], const size_t *len, u8 *mac)
843+{
844+ return hmac_vector(key, key_len, num_elem, addr, len, mac,
845+ MBEDTLS_MD_SHA256);
846+}
847+
848+int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
849+ u8 *mac)
850+{
851+ return hmac_vector(key, key_len, 1, &data, &data_len, mac,
852+ MBEDTLS_MD_SHA256);
853+}
854+#endif
855+
856+#ifdef MBEDTLS_SHA1_C
857+int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
858+ const u8 *addr[], const size_t *len, u8 *mac)
859+{
860+ return hmac_vector(key, key_len, num_elem, addr, len, mac,
861+ MBEDTLS_MD_SHA1);
862+}
863+
864+int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
865+ u8 *mac)
866+{
867+ return hmac_vector(key, key_len, 1, &data, &data_len, mac,
868+ MBEDTLS_MD_SHA1);
869+}
870+#endif
871+
872+#ifdef MBEDTLS_MD5_C
873+int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
874+ const u8 *addr[], const size_t *len, u8 *mac)
875+{
876+ return hmac_vector(key, key_len, num_elem, addr, len, mac,
877+ MBEDTLS_MD_MD5);
878+}
879+
880+int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
881+ u8 *mac)
882+{
883+ return hmac_vector(key, key_len, 1, &data, &data_len, mac,
884+ MBEDTLS_MD_MD5);
885+}
886+#endif
887+
888+
889+#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA512_C)
890+
891+#if defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA256) \
892+ || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA384) \
893+ || defined(CRYPTO_MBEDTLS_HMAC_KDF_SHA512)
894+
895+#include <mbedtls/hkdf.h>
896+
897+/* sha256-kdf.c sha384-kdf.c sha512-kdf.c */
898+
899+/* HMAC-SHA256 KDF (RFC 5295) and HKDF-Expand(SHA256) (RFC 5869) */
900+/* HMAC-SHA384 KDF (RFC 5295) and HKDF-Expand(SHA384) (RFC 5869) */
901+/* HMAC-SHA512 KDF (RFC 5295) and HKDF-Expand(SHA512) (RFC 5869) */
902+__attribute_noinline__
903+static int hmac_kdf_expand(const u8 *prk, size_t prk_len,
904+ const char *label, const u8 *info, size_t info_len,
905+ u8 *okm, size_t okm_len, mbedtls_md_type_t md_type)
906+{
907+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type);
908+ #ifdef MBEDTLS_HKDF_C
909+ if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */
910+ return mbedtls_hkdf_expand(md_info, prk, prk_len, info,
911+ info_len, okm, okm_len) ? -1 : 0;
912+ #endif
913+
914+ const size_t mac_len = mbedtls_md_get_size(md_info);
915+ /* okm_len must not exceed 255 times hash len (RFC 5869 Section 2.3) */
916+ if (okm_len > ((mac_len << 8) - mac_len))
917+ return -1;
918+
919+ mbedtls_md_context_t ctx;
920+ mbedtls_md_init(&ctx);
921+ if (mbedtls_md_setup(&ctx, md_info, 1) != 0) {
922+ mbedtls_md_free(&ctx);
923+ return -1;
924+ }
925+ mbedtls_md_hmac_starts(&ctx, prk, prk_len);
926+
927+ u8 iter = 1;
928+ const u8 *addr[4] = { okm, (const u8 *)label, info, &iter };
929+ size_t len[4] = { 0, label ? os_strlen(label)+1 : 0, info_len, 1 };
930+
931+ for (; okm_len >= mac_len; okm_len -= mac_len, ++iter) {
932+ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i)
933+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
934+ mbedtls_md_hmac_finish(&ctx, okm);
935+ mbedtls_md_hmac_reset(&ctx);
936+ addr[0] = okm;
937+ okm += mac_len;
938+ len[0] = mac_len; /*(include digest in subsequent rounds)*/
939+ }
940+
941+ if (okm_len) {
942+ u8 hash[MBEDTLS_MD_MAX_SIZE];
943+ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i)
944+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
945+ mbedtls_md_hmac_finish(&ctx, hash);
946+ os_memcpy(okm, hash, okm_len);
947+ forced_memzero(hash, mac_len);
948+ }
949+
950+ mbedtls_md_free(&ctx);
951+ return 0;
952+}
953+
954+#ifdef MBEDTLS_SHA512_C
955+#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA512
956+int hmac_sha512_kdf(const u8 *secret, size_t secret_len,
957+ const char *label, const u8 *seed, size_t seed_len,
958+ u8 *out, size_t outlen)
959+{
960+ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len,
961+ out, outlen, MBEDTLS_MD_SHA512);
962+}
963+#endif
964+
965+#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA384
966+int hmac_sha384_kdf(const u8 *secret, size_t secret_len,
967+ const char *label, const u8 *seed, size_t seed_len,
968+ u8 *out, size_t outlen)
969+{
970+ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len,
971+ out, outlen, MBEDTLS_MD_SHA384);
972+}
973+#endif
974+#endif
975+
976+#ifdef MBEDTLS_SHA256_C
977+#ifdef CRYPTO_MBEDTLS_HMAC_KDF_SHA256
978+int hmac_sha256_kdf(const u8 *secret, size_t secret_len,
979+ const char *label, const u8 *seed, size_t seed_len,
980+ u8 *out, size_t outlen)
981+{
982+ return hmac_kdf_expand(secret, secret_len, label, seed, seed_len,
983+ out, outlen, MBEDTLS_MD_SHA256);
984+}
985+#endif
986+#endif
987+
988+#endif /* CRYPTO_MBEDTLS_HMAC_KDF_* */
989+
990+
991+/* sha256-prf.c sha384-prf.c sha512-prf.c */
992+
993+/* hmac_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function */
994+__attribute_noinline__
995+static int hmac_prf_bits(const u8 *key, size_t key_len, const char *label,
996+ const u8 *data, size_t data_len, u8 *buf,
997+ size_t buf_len_bits, mbedtls_md_type_t md_type)
998+{
999+ mbedtls_md_context_t ctx;
1000+ mbedtls_md_init(&ctx);
1001+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type);
1002+ if (mbedtls_md_setup(&ctx, md_info, 1) != 0) {
1003+ mbedtls_md_free(&ctx);
1004+ return -1;
1005+ }
1006+ mbedtls_md_hmac_starts(&ctx, key, key_len);
1007+
1008+ u16 ctr, n_le = host_to_le16(buf_len_bits);
1009+ const u8 * const addr[] = { (u8 *)&ctr,(u8 *)label,data,(u8 *)&n_le };
1010+ const size_t len[] = { 2, os_strlen(label), data_len, 2 };
1011+ const size_t mac_len = mbedtls_md_get_size(md_info);
1012+ size_t buf_len = (buf_len_bits + 7) / 8;
1013+ for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr) {
1014+ #if __BYTE_ORDER == __BIG_ENDIAN
1015+ ctr = host_to_le16(ctr);
1016+ #endif
1017+ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i)
1018+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
1019+ mbedtls_md_hmac_finish(&ctx, buf);
1020+ mbedtls_md_hmac_reset(&ctx);
1021+ buf += mac_len;
1022+ #if __BYTE_ORDER == __BIG_ENDIAN
1023+ ctr = le_to_host16(ctr);
1024+ #endif
1025+ }
1026+
1027+ if (buf_len) {
1028+ u8 hash[MBEDTLS_MD_MAX_SIZE];
1029+ #if __BYTE_ORDER == __BIG_ENDIAN
1030+ ctr = host_to_le16(ctr);
1031+ #endif
1032+ for (size_t i = 0; i < ARRAY_SIZE(addr); ++i)
1033+ mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
1034+ mbedtls_md_hmac_finish(&ctx, hash);
1035+ os_memcpy(buf, hash, buf_len);
1036+ buf += buf_len;
1037+ forced_memzero(hash, mac_len);
1038+ }
1039+
1040+ /* Mask out unused bits in last octet if it does not use all the bits */
1041+ if ((buf_len_bits &= 0x7))
1042+ buf[-1] &= (u8)(0xff << (8 - buf_len_bits));
1043+
1044+ mbedtls_md_free(&ctx);
1045+ return 0;
1046+}
1047+
1048+#ifdef MBEDTLS_SHA512_C
1049+int sha512_prf(const u8 *key, size_t key_len, const char *label,
1050+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
1051+{
1052+ return hmac_prf_bits(key, key_len, label, data, data_len, buf,
1053+ buf_len * 8, MBEDTLS_MD_SHA512);
1054+}
1055+
1056+int sha384_prf(const u8 *key, size_t key_len, const char *label,
1057+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
1058+{
1059+ return hmac_prf_bits(key, key_len, label, data, data_len, buf,
1060+ buf_len * 8, MBEDTLS_MD_SHA384);
1061+}
1062+#endif
1063+
1064+#ifdef MBEDTLS_SHA256_C
1065+int sha256_prf(const u8 *key, size_t key_len, const char *label,
1066+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
1067+{
1068+ return hmac_prf_bits(key, key_len, label, data, data_len, buf,
1069+ buf_len * 8, MBEDTLS_MD_SHA256);
1070+}
1071+
1072+int sha256_prf_bits(const u8 *key, size_t key_len, const char *label,
1073+ const u8 *data, size_t data_len, u8 *buf,
1074+ size_t buf_len_bits)
1075+{
1076+ return hmac_prf_bits(key, key_len, label, data, data_len, buf,
1077+ buf_len_bits, MBEDTLS_MD_SHA256);
1078+}
1079+#endif
1080+
1081+#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA512_C */
1082+
1083+
1084+#ifdef MBEDTLS_SHA1_C
1085+
1086+/* sha1-prf.c */
1087+
1088+/* sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) */
1089+
1090+int sha1_prf(const u8 *key, size_t key_len, const char *label,
1091+ const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
1092+{
1093+ /*(note: algorithm differs from hmac_prf_bits() */
1094+ /*(note: smaller code size instead of expanding hmac_sha1_vector()
1095+ * as is done in hmac_prf_bits(); not expecting large num of loops) */
1096+ u8 counter = 0;
1097+ const u8 *addr[] = { (u8 *)label, data, &counter };
1098+ const size_t len[] = { os_strlen(label)+1, data_len, 1 };
1099+
1100+ for (; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++counter) {
1101+ if (hmac_sha1_vector(key, key_len, 3, addr, len, buf))
1102+ return -1;
1103+ buf += SHA1_MAC_LEN;
1104+ }
1105+
1106+ if (buf_len) {
1107+ u8 hash[SHA1_MAC_LEN];
1108+ if (hmac_sha1_vector(key, key_len, 3, addr, len, hash))
1109+ return -1;
1110+ os_memcpy(buf, hash, buf_len);
1111+ forced_memzero(hash, sizeof(hash));
1112+ }
1113+
1114+ return 0;
1115+}
1116+
1117+#ifdef CRYPTO_MBEDTLS_SHA1_T_PRF
1118+
1119+/* sha1-tprf.c */
1120+
1121+/* sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) (RFC 4851,Section 5.5)*/
1122+
1123+int sha1_t_prf(const u8 *key, size_t key_len, const char *label,
1124+ const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
1125+{
1126+ /*(note: algorithm differs from hmac_prf_bits() and hmac_kdf() above)*/
1127+ /*(note: smaller code size instead of expanding hmac_sha1_vector()
1128+ * as is done in hmac_prf_bits(); not expecting large num of loops) */
1129+ u8 ctr;
1130+ u16 olen = host_to_be16(buf_len);
1131+ const u8 *addr[] = { buf, (u8 *)label, seed, (u8 *)&olen, &ctr };
1132+ size_t len[] = { 0, os_strlen(label)+1, seed_len, 2, 1 };
1133+
1134+ for (ctr = 1; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++ctr) {
1135+ if (hmac_sha1_vector(key, key_len, 5, addr, len, buf))
1136+ return -1;
1137+ addr[0] = buf;
1138+ buf += SHA1_MAC_LEN;
1139+ len[0] = SHA1_MAC_LEN; /*(include digest in subsequent rounds)*/
1140+ }
1141+
1142+ if (buf_len) {
1143+ u8 hash[SHA1_MAC_LEN];
1144+ if (hmac_sha1_vector(key, key_len, 5, addr, len, hash))
1145+ return -1;
1146+ os_memcpy(buf, hash, buf_len);
1147+ forced_memzero(hash, sizeof(hash));
1148+ }
1149+
1150+ return 0;
1151+}
1152+
1153+#endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */
1154+
1155+#endif /* MBEDTLS_SHA1_C */
1156+
1157+
1158+#ifdef CRYPTO_MBEDTLS_DES_ENCRYPT
1159+#ifdef MBEDTLS_DES_C
1160+#include <mbedtls/des.h>
1161+int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
1162+{
1163+ u8 pkey[8], next, tmp;
1164+ int i;
1165+
1166+ /* Add parity bits to the key */
1167+ next = 0;
1168+ for (i = 0; i < 7; i++) {
1169+ tmp = key[i];
1170+ pkey[i] = (tmp >> i) | next | 1;
1171+ next = tmp << (7 - i);
1172+ }
1173+ pkey[i] = next | 1;
1174+
1175+ mbedtls_des_context des;
1176+ mbedtls_des_init(&des);
1177+ int ret = mbedtls_des_setkey_enc(&des, pkey)
1178+ || mbedtls_des_crypt_ecb(&des, clear, cypher) ? -1 : 0;
1179+ mbedtls_des_free(&des);
1180+ return ret;
1181+}
1182+#else
1183+#include "des-internal.c"/* pull in hostap local implementation */
1184+#endif
1185+#endif
1186+
1187+
1188+#ifdef CRYPTO_MBEDTLS_PBKDF2_SHA1
1189+/* sha1-pbkdf2.c */
1190+#include <mbedtls/pkcs5.h>
1191+int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
1192+ int iterations, u8 *buf, size_t buflen)
1193+{
1194+ #if MBEDTLS_VERSION_NUMBER >= 0x03020200 /* mbedtls 3.2.2 */
1195+ return mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1,
1196+ (const u8 *)passphrase, os_strlen(passphrase),
1197+ ssid, ssid_len, iterations, 32, buf) ? -1 : 0;
1198+ #else
1199+ const mbedtls_md_info_t *md_info;
1200+ md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
1201+ if (md_info == NULL)
1202+ return -1;
1203+ mbedtls_md_context_t ctx;
1204+ mbedtls_md_init(&ctx);
1205+ int ret = mbedtls_md_setup(&ctx, md_info, 1)
1206+ || mbedtls_pkcs5_pbkdf2_hmac(&ctx,
1207+ (const u8 *)passphrase, os_strlen(passphrase),
1208+ ssid, ssid_len, iterations, 32, buf) ? -1 : 0;
1209+ mbedtls_md_free(&ctx);
1210+ return ret;
1211+ #endif
1212+}
1213+#endif
1214+
1215+
1216+/*#include "aes.h"*/ /* prototypes also included in "crypto.h" */
1217+
1218+static void *aes_crypt_init_mode(const u8 *key, size_t len, int mode)
1219+{
1220+ mbedtls_aes_context *aes = os_malloc(sizeof(*aes));
1221+ if (!aes)
1222+ return NULL;
1223+
1224+ mbedtls_aes_init(aes);
1225+ if ((mode == MBEDTLS_AES_ENCRYPT
1226+ ? mbedtls_aes_setkey_enc(aes, key, len * 8)
1227+ : mbedtls_aes_setkey_dec(aes, key, len * 8)) == 0)
1228+ return aes;
1229+
1230+ mbedtls_aes_free(aes);
1231+ os_free(aes);
1232+ return NULL;
1233+}
1234+
1235+void *aes_encrypt_init(const u8 *key, size_t len)
1236+{
1237+ return aes_crypt_init_mode(key, len, MBEDTLS_AES_ENCRYPT);
1238+}
1239+
1240+int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
1241+{
1242+ return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt);
1243+}
1244+
1245+void aes_encrypt_deinit(void *ctx)
1246+{
1247+ mbedtls_aes_free(ctx);
1248+ os_free(ctx);
1249+}
1250+
1251+void *aes_decrypt_init(const u8 *key, size_t len)
1252+{
1253+ return aes_crypt_init_mode(key, len, MBEDTLS_AES_DECRYPT);
1254+}
1255+
1256+int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
1257+{
1258+ return mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_DECRYPT, crypt, plain);
1259+}
1260+
1261+void aes_decrypt_deinit(void *ctx)
1262+{
1263+ mbedtls_aes_free(ctx);
1264+ os_free(ctx);
1265+}
1266+
1267+
1268+#include "aes_wrap.h"
1269+
1270+
1271+#ifdef MBEDTLS_NIST_KW_C
1272+
1273+#include <mbedtls/nist_kw.h>
1274+
1275+/* aes-wrap.c */
1276+int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
1277+{
1278+ mbedtls_nist_kw_context ctx;
1279+ mbedtls_nist_kw_init(&ctx);
1280+ size_t olen;
1281+ int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
1282+ kek, kek_len*8, 1)
1283+ || mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, n*8,
1284+ cipher, &olen, (n+1)*8) ? -1 : 0;
1285+ mbedtls_nist_kw_free(&ctx);
1286+ return ret;
1287+}
1288+
1289+/* aes-unwrap.c */
1290+int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain)
1291+{
1292+ mbedtls_nist_kw_context ctx;
1293+ mbedtls_nist_kw_init(&ctx);
1294+ size_t olen;
1295+ int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES,
1296+ kek, kek_len*8, 0)
1297+ || mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher,
1298+ (n+1)*8, plain, &olen, n*8) ? -1 : 0;
1299+ mbedtls_nist_kw_free(&ctx);
1300+ return ret;
1301+}
1302+
1303+#else
1304+
1305+#ifndef CRYPTO_MBEDTLS_CONFIG_FIPS
1306+#include "aes-wrap.c" /* pull in hostap local implementation */
1307+#include "aes-unwrap.c" /* pull in hostap local implementation */
1308+#endif
1309+
1310+#endif /* MBEDTLS_NIST_KW_C */
1311+
1312+
1313+#ifdef MBEDTLS_CMAC_C
1314+
1315+/* aes-omac1.c */
1316+
1317+#include <mbedtls/cmac.h>
1318+
1319+int omac1_aes_vector(
1320+ const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[],
1321+ const size_t *len, u8 *mac)
1322+{
1323+ mbedtls_cipher_type_t cipher_type;
1324+ switch (key_len) {
1325+ case 16: cipher_type = MBEDTLS_CIPHER_AES_128_ECB; break;
1326+ case 24: cipher_type = MBEDTLS_CIPHER_AES_192_ECB; break;
1327+ case 32: cipher_type = MBEDTLS_CIPHER_AES_256_ECB; break;
1328+ default: return -1;
1329+ }
1330+ const mbedtls_cipher_info_t *cipher_info;
1331+ cipher_info = mbedtls_cipher_info_from_type(cipher_type);
1332+ if (cipher_info == NULL)
1333+ return -1;
1334+
1335+ mbedtls_cipher_context_t ctx;
1336+ mbedtls_cipher_init(&ctx);
1337+ int ret = -1;
1338+ if (mbedtls_cipher_setup(&ctx, cipher_info) == 0
1339+ && mbedtls_cipher_cmac_starts(&ctx, key, key_len*8) == 0) {
1340+ ret = 0;
1341+ for (size_t i = 0; i < num_elem && ret == 0; ++i)
1342+ ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]);
1343+ }
1344+ if (ret == 0)
1345+ ret = mbedtls_cipher_cmac_finish(&ctx, mac);
1346+ mbedtls_cipher_free(&ctx);
1347+ return ret ? -1 : 0;
1348+}
1349+
1350+int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1351+ const u8 *addr[], const size_t *len,
1352+ u8 *mac)
1353+{
1354+ return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1355+}
1356+
1357+int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1358+{
1359+ return omac1_aes_vector(key, 16, 1, &data, &data_len, mac);
1360+}
1361+
1362+int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1363+{
1364+ return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1365+}
1366+
1367+#else
1368+
1369+#include "aes-omac1.c" /* pull in hostap local implementation */
1370+
1371+#ifndef MBEDTLS_AES_BLOCK_SIZE
1372+#define MBEDTLS_AES_BLOCK_SIZE 16
1373+#endif
1374+
1375+#endif /* MBEDTLS_CMAC_C */
1376+
1377+
1378+/* These interfaces can be inefficient when used in loops, as the overhead of
1379+ * initialization each call is large for each block input (e.g. 16 bytes) */
1380+
1381+
1382+/* aes-encblock.c */
1383+int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out)
1384+{
1385+ mbedtls_aes_context aes;
1386+ mbedtls_aes_init(&aes);
1387+ int ret = mbedtls_aes_setkey_enc(&aes, key, 128)
1388+ || mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, in, out)
1389+ ? -1
1390+ : 0;
1391+ mbedtls_aes_free(&aes);
1392+ return ret;
1393+}
1394+
1395+
1396+/* aes-ctr.c */
1397+int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce,
1398+ u8 *data, size_t data_len)
1399+{
1400+ unsigned char counter[MBEDTLS_AES_BLOCK_SIZE];
1401+ unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE];
1402+ os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE);/*(must be writable)*/
1403+
1404+ mbedtls_aes_context ctx;
1405+ mbedtls_aes_init(&ctx);
1406+ size_t nc_off = 0;
1407+ int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len*8)
1408+ || mbedtls_aes_crypt_ctr(&ctx, data_len, &nc_off,
1409+ counter, stream_block,
1410+ data, data) ? -1 : 0;
1411+ forced_memzero(stream_block, sizeof(stream_block));
1412+ mbedtls_aes_free(&ctx);
1413+ return ret;
1414+}
1415+
1416+int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
1417+ u8 *data, size_t data_len)
1418+{
1419+ return aes_ctr_encrypt(key, 16, nonce, data, data_len);
1420+}
1421+
1422+
1423+/* aes-cbc.c */
1424+static int aes_128_cbc_oper(const u8 *key, const u8 *iv,
1425+ u8 *data, size_t data_len, int mode)
1426+{
1427+ unsigned char ivec[MBEDTLS_AES_BLOCK_SIZE];
1428+ os_memcpy(ivec, iv, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/
1429+
1430+ mbedtls_aes_context ctx;
1431+ mbedtls_aes_init(&ctx);
1432+ int ret = (mode == MBEDTLS_AES_ENCRYPT
1433+ ? mbedtls_aes_setkey_enc(&ctx, key, 128)
1434+ : mbedtls_aes_setkey_dec(&ctx, key, 128))
1435+ || mbedtls_aes_crypt_cbc(&ctx, mode, data_len, ivec, data, data);
1436+ mbedtls_aes_free(&ctx);
1437+ return ret ? -1 : 0;
1438+}
1439+
1440+int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
1441+{
1442+ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT);
1443+}
1444+
1445+int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
1446+{
1447+ return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT);
1448+}
1449+
1450+
1451+/*
1452+ * Much of the following is documented in crypto.h as for CONFIG_TLS=internal
1453+ * but such comments are not accurate:
1454+ *
1455+ * "This function is only used with internal TLSv1 implementation
1456+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
1457+ * to implement this."
1458+ */
1459+
1460+
1461+#ifdef CRYPTO_MBEDTLS_CRYPTO_CIPHER
1462+
1463+#include <mbedtls/cipher.h>
1464+
1465+struct crypto_cipher
1466+{
1467+ mbedtls_cipher_context_t ctx_enc;
1468+ mbedtls_cipher_context_t ctx_dec;
1469+};
1470+
1471+struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
1472+ const u8 *iv, const u8 *key,
1473+ size_t key_len)
1474+{
1475+ /* IKEv2 src/eap_common/ikev2_common.c:ikev2_{encr,decr}_encrypt()
1476+ * uses one of CRYPTO_CIPHER_ALG_AES or CRYPTO_CIPHER_ALG_3DES */
1477+
1478+ mbedtls_cipher_type_t cipher_type;
1479+ size_t iv_len;
1480+ switch (alg) {
1481+ #ifdef MBEDTLS_ARC4_C
1482+ #if 0
1483+ case CRYPTO_CIPHER_ALG_RC4:
1484+ cipher_type = MBEDTLS_CIPHER_ARC4_128;
1485+ iv_len = 0;
1486+ break;
1487+ #endif
1488+ #endif
1489+ #ifdef MBEDTLS_AES_C
1490+ case CRYPTO_CIPHER_ALG_AES:
1491+ if (key_len == 16) cipher_type = MBEDTLS_CIPHER_AES_128_CTR;
1492+ if (key_len == 24) cipher_type = MBEDTLS_CIPHER_AES_192_CTR;
1493+ if (key_len == 32) cipher_type = MBEDTLS_CIPHER_AES_256_CTR;
1494+ iv_len = 16;
1495+ break;
1496+ #endif
1497+ #ifdef MBEDTLS_DES_C
1498+ case CRYPTO_CIPHER_ALG_3DES:
1499+ cipher_type = MBEDTLS_CIPHER_DES_EDE3_CBC;
1500+ iv_len = 8;
1501+ break;
1502+ #if 0
1503+ case CRYPTO_CIPHER_ALG_DES:
1504+ cipher_type = MBEDTLS_CIPHER_DES_CBC;
1505+ iv_len = 8;
1506+ break;
1507+ #endif
1508+ #endif
1509+ default:
1510+ return NULL;
1511+ }
1512+
1513+ const mbedtls_cipher_info_t *cipher_info;
1514+ cipher_info = mbedtls_cipher_info_from_type(cipher_type);
1515+ if (cipher_info == NULL)
1516+ return NULL;
1517+
1518+ key_len *= 8; /* key_bitlen */
1519+ #if 0 /*(were key_bitlen not already available)*/
1520+ #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */
1521+ key_len = mbedtls_cipher_info_get_key_bitlen(cipher_info);
1522+ #else
1523+ key_len = cipher_info->MBEDTLS_PRIVATE(key_bitlen);
1524+ #endif
1525+ #endif
1526+
1527+ #if 0 /*(were iv_len not known above, would need MBEDTLS_PRIVATE(iv_size))*/
1528+ iv_len = cipher_info->MBEDTLS_PRIVATE(iv_size);
1529+ #endif
1530+
1531+ struct crypto_cipher *ctx = os_malloc(sizeof(*ctx));
1532+ if (!ctx)
1533+ return NULL;
1534+
1535+ mbedtls_cipher_init(&ctx->ctx_enc);
1536+ mbedtls_cipher_init(&ctx->ctx_dec);
1537+ if ( mbedtls_cipher_setup(&ctx->ctx_enc,cipher_info) == 0
1538+ && mbedtls_cipher_setup(&ctx->ctx_dec,cipher_info) == 0
1539+ && mbedtls_cipher_setkey(&ctx->ctx_enc,key,key_len,MBEDTLS_ENCRYPT) == 0
1540+ && mbedtls_cipher_setkey(&ctx->ctx_dec,key,key_len,MBEDTLS_DECRYPT) == 0
1541+ && mbedtls_cipher_set_iv(&ctx->ctx_enc,iv,iv_len) == 0
1542+ && mbedtls_cipher_set_iv(&ctx->ctx_dec,iv,iv_len) == 0
1543+ && mbedtls_cipher_reset(&ctx->ctx_enc) == 0
1544+ && mbedtls_cipher_reset(&ctx->ctx_dec) == 0) {
1545+ return ctx;
1546+ }
1547+
1548+ mbedtls_cipher_free(&ctx->ctx_enc);
1549+ mbedtls_cipher_free(&ctx->ctx_dec);
1550+ os_free(ctx);
1551+ return NULL;
1552+}
1553+
1554+int crypto_cipher_encrypt(struct crypto_cipher *ctx,
1555+ const u8 *plain, u8 *crypt, size_t len)
1556+{
1557+ size_t olen = 0; /*(poor interface above; unknown size of u8 *crypt)*/
1558+ return (mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen)
1559+ || mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen)) ? -1 : 0;
1560+}
1561+
1562+int crypto_cipher_decrypt(struct crypto_cipher *ctx,
1563+ const u8 *crypt, u8 *plain, size_t len)
1564+{
1565+ size_t olen = 0; /*(poor interface above; unknown size of u8 *plain)*/
1566+ return (mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen)
1567+ || mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen)) ? -1 : 0;
1568+}
1569+
1570+void crypto_cipher_deinit(struct crypto_cipher *ctx)
1571+{
1572+ mbedtls_cipher_free(&ctx->ctx_enc);
1573+ mbedtls_cipher_free(&ctx->ctx_dec);
1574+ os_free(ctx);
1575+}
1576+
1577+#endif /* CRYPTO_MBEDTLS_CRYPTO_CIPHER */
1578+
1579+
1580+#ifdef CRYPTO_MBEDTLS_CRYPTO_HASH
1581+
1582+struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
1583+ size_t key_len)
1584+{
1585+ mbedtls_md_type_t md_type;
1586+ int is_hmac = 0;
1587+
1588+ switch (alg) {
1589+ #ifdef MBEDTLS_MD5_C
1590+ case CRYPTO_HASH_ALG_MD5:
1591+ md_type = MBEDTLS_MD_MD5;
1592+ break;
1593+ #endif
1594+ #ifdef MBEDTLS_SHA1_C
1595+ case CRYPTO_HASH_ALG_SHA1:
1596+ md_type = MBEDTLS_MD_SHA1;
1597+ break;
1598+ #endif
1599+ #ifdef MBEDTLS_MD5_C
1600+ case CRYPTO_HASH_ALG_HMAC_MD5:
1601+ md_type = MBEDTLS_MD_MD5;
1602+ is_hmac = 1;
1603+ break;
1604+ #endif
1605+ #ifdef MBEDTLS_SHA1_C
1606+ case CRYPTO_HASH_ALG_HMAC_SHA1:
1607+ md_type = MBEDTLS_MD_SHA1;
1608+ is_hmac = 1;
1609+ break;
1610+ #endif
1611+ #ifdef MBEDTLS_SHA256_C
1612+ case CRYPTO_HASH_ALG_SHA256:
1613+ md_type = MBEDTLS_MD_SHA256;
1614+ break;
1615+ case CRYPTO_HASH_ALG_HMAC_SHA256:
1616+ md_type = MBEDTLS_MD_SHA256;
1617+ is_hmac = 1;
1618+ break;
1619+ #endif
1620+ #ifdef MBEDTLS_SHA512_C
1621+ case CRYPTO_HASH_ALG_SHA384:
1622+ md_type = MBEDTLS_MD_SHA384;
1623+ break;
1624+ case CRYPTO_HASH_ALG_SHA512:
1625+ md_type = MBEDTLS_MD_SHA512;
1626+ break;
1627+ #endif
1628+ default:
1629+ return NULL;
1630+ }
1631+
1632+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type);
1633+ if (!md_info)
1634+ return NULL;
1635+
1636+ mbedtls_md_context_t *mctx = os_malloc(sizeof(*mctx));
1637+ if (mctx == NULL)
1638+ return NULL;
1639+
1640+ mbedtls_md_init(mctx);
1641+ if (mbedtls_md_setup(mctx, md_info, is_hmac) != 0) {
1642+ os_free(mctx);
1643+ return NULL;
1644+ }
1645+
1646+ if (is_hmac)
1647+ mbedtls_md_hmac_starts(mctx, key, key_len);
1648+ else
1649+ mbedtls_md_starts(mctx);
1650+ return (struct crypto_hash *)((uintptr_t)mctx | is_hmac);
1651+}
1652+
1653+void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
1654+{
1655+ mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL);
1656+ #if 0
1657+ /*(mbedtls_md_hmac_update() and mbedtls_md_update()
1658+ * make same modifications under the hood in mbedtls)*/
1659+ if ((uintptr_t)ctx & 1uL)
1660+ mbedtls_md_hmac_update(mctx, data, len);
1661+ else
1662+ #endif
1663+ mbedtls_md_update(mctx, data, len);
1664+}
1665+
1666+int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
1667+{
1668+ mbedtls_md_context_t *mctx = (mbedtls_md_context_t*)((uintptr_t)ctx & ~1uL);
1669+ if (mac != NULL && len != NULL) { /*(NULL if caller just freeing context)*/
1670+ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */
1671+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_ctx(mctx);
1672+ #else
1673+ const mbedtls_md_info_t *md_info = mctx->MBEDTLS_PRIVATE(md_info);
1674+ #endif
1675+ size_t maclen = mbedtls_md_get_size(md_info);
1676+ if (*len < maclen) {
1677+ *len = maclen;
1678+ /*(note: ctx not freed; can call again with larger *len)*/
1679+ return -1;
1680+ }
1681+ *len = maclen;
1682+ if ((uintptr_t)ctx & 1uL)
1683+ mbedtls_md_hmac_finish(mctx, mac);
1684+ else
1685+ mbedtls_md_finish(mctx, mac);
1686+ }
1687+ mbedtls_md_free(mctx);
1688+ os_free(mctx);
1689+ return 0;
1690+}
1691+
1692+#endif /* CRYPTO_MBEDTLS_CRYPTO_HASH */
1693+
1694+
1695+#ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM
1696+
1697+#include <mbedtls/bignum.h>
1698+
1699+/* crypto.h bignum interfaces */
1700+
1701+struct crypto_bignum *crypto_bignum_init(void)
1702+{
1703+ mbedtls_mpi *bn = os_malloc(sizeof(*bn));
1704+ if (bn)
1705+ mbedtls_mpi_init(bn);
1706+ return (struct crypto_bignum *)bn;
1707+}
1708+
1709+struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len)
1710+{
1711+ mbedtls_mpi *bn = os_malloc(sizeof(*bn));
1712+ if (bn) {
1713+ mbedtls_mpi_init(bn);
1714+ if (mbedtls_mpi_read_binary(bn, buf, len) == 0)
1715+ return (struct crypto_bignum *)bn;
1716+ }
1717+
1718+ os_free(bn);
1719+ return NULL;
1720+}
1721+
1722+struct crypto_bignum *crypto_bignum_init_uint(unsigned int val)
1723+{
1724+ #if 0 /*(hostap use of this interface passes int, not uint)*/
1725+ val = host_to_be32(val);
1726+ return crypto_bignum_init_set((const u8 *)&val, sizeof(val));
1727+ #else
1728+ mbedtls_mpi *bn = os_malloc(sizeof(*bn));
1729+ if (bn) {
1730+ mbedtls_mpi_init(bn);
1731+ if (mbedtls_mpi_lset(bn, (int)val) == 0)
1732+ return (struct crypto_bignum *)bn;
1733+ }
1734+
1735+ os_free(bn);
1736+ return NULL;
1737+ #endif
1738+}
1739+
1740+void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1741+{
1742+ mbedtls_mpi_free((mbedtls_mpi *)n);
1743+ os_free(n);
1744+}
1745+
1746+int crypto_bignum_to_bin(const struct crypto_bignum *a,
1747+ u8 *buf, size_t buflen, size_t padlen)
1748+{
1749+ size_t n = mbedtls_mpi_size((mbedtls_mpi *)a);
1750+ if (n < padlen)
1751+ n = padlen;
1752+ return n > buflen || mbedtls_mpi_write_binary((mbedtls_mpi *)a, buf, n)
1753+ ? -1
1754+ : (int)(n);
1755+}
1756+
1757+int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
1758+{
1759+ /*assert(r != m);*//* r must not be same as m for mbedtls_mpi_random()*/
1760+ #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */
1761+ return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m,
1762+ mbedtls_ctr_drbg_random,
1763+ crypto_mbedtls_ctr_drbg()) ? -1 : 0;
1764+ #else
1765+ /* (needed by EAP_PWD, SAE, DPP) */
1766+ wpa_printf(MSG_ERROR,
1767+ "mbedtls 2.27.0 or later required for mbedtls_mpi_random()");
1768+ return -1;
1769+ #endif
1770+}
1771+
1772+int crypto_bignum_add(const struct crypto_bignum *a,
1773+ const struct crypto_bignum *b,
1774+ struct crypto_bignum *c)
1775+{
1776+ return mbedtls_mpi_add_mpi((mbedtls_mpi *)c,
1777+ (const mbedtls_mpi *)a,
1778+ (const mbedtls_mpi *)b) ? -1 : 0;
1779+}
1780+
1781+int crypto_bignum_mod(const struct crypto_bignum *a,
1782+ const struct crypto_bignum *b,
1783+ struct crypto_bignum *c)
1784+{
1785+ return mbedtls_mpi_mod_mpi((mbedtls_mpi *)c,
1786+ (const mbedtls_mpi *)a,
1787+ (const mbedtls_mpi *)b) ? -1 : 0;
1788+}
1789+
1790+int crypto_bignum_exptmod(const struct crypto_bignum *a,
1791+ const struct crypto_bignum *b,
1792+ const struct crypto_bignum *c,
1793+ struct crypto_bignum *d)
1794+{
1795+ /* (check if input params match d; d is the result) */
1796+ /* (a == d) is ok in current mbedtls implementation */
1797+ if (b == d || c == d) { /*(not ok; store result in intermediate)*/
1798+ mbedtls_mpi R;
1799+ mbedtls_mpi_init(&R);
1800+ int rc = mbedtls_mpi_exp_mod(&R,
1801+ (const mbedtls_mpi *)a,
1802+ (const mbedtls_mpi *)b,
1803+ (const mbedtls_mpi *)c,
1804+ NULL)
1805+ || mbedtls_mpi_copy((mbedtls_mpi *)d, &R) ? -1 : 0;
1806+ mbedtls_mpi_free(&R);
1807+ return rc;
1808+ }
1809+ else {
1810+ return mbedtls_mpi_exp_mod((mbedtls_mpi *)d,
1811+ (const mbedtls_mpi *)a,
1812+ (const mbedtls_mpi *)b,
1813+ (const mbedtls_mpi *)c,
1814+ NULL) ? -1 : 0;
1815+ }
1816+}
1817+
1818+int crypto_bignum_inverse(const struct crypto_bignum *a,
1819+ const struct crypto_bignum *b,
1820+ struct crypto_bignum *c)
1821+{
1822+ return mbedtls_mpi_inv_mod((mbedtls_mpi *)c,
1823+ (const mbedtls_mpi *)a,
1824+ (const mbedtls_mpi *)b) ? -1 : 0;
1825+}
1826+
1827+int crypto_bignum_sub(const struct crypto_bignum *a,
1828+ const struct crypto_bignum *b,
1829+ struct crypto_bignum *c)
1830+{
1831+ return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c,
1832+ (const mbedtls_mpi *)a,
1833+ (const mbedtls_mpi *)b) ? -1 : 0;
1834+}
1835+
1836+int crypto_bignum_div(const struct crypto_bignum *a,
1837+ const struct crypto_bignum *b,
1838+ struct crypto_bignum *c)
1839+{
1840+ /*(most current use of this crypto.h interface has a == c (result),
1841+ * so store result in an intermediate to avoid overwritten input)*/
1842+ mbedtls_mpi R;
1843+ mbedtls_mpi_init(&R);
1844+ int rc = mbedtls_mpi_div_mpi(&R, NULL,
1845+ (const mbedtls_mpi *)a,
1846+ (const mbedtls_mpi *)b)
1847+ || mbedtls_mpi_copy((mbedtls_mpi *)c, &R) ? -1 : 0;
1848+ mbedtls_mpi_free(&R);
1849+ return rc;
1850+}
1851+
1852+int crypto_bignum_addmod(const struct crypto_bignum *a,
1853+ const struct crypto_bignum *b,
1854+ const struct crypto_bignum *c,
1855+ struct crypto_bignum *d)
1856+{
1857+ return mbedtls_mpi_add_mpi((mbedtls_mpi *)d,
1858+ (const mbedtls_mpi *)a,
1859+ (const mbedtls_mpi *)b)
1860+ || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d,
1861+ (mbedtls_mpi *)d,
1862+ (const mbedtls_mpi *)c) ? -1 : 0;
1863+}
1864+
1865+int crypto_bignum_mulmod(const struct crypto_bignum *a,
1866+ const struct crypto_bignum *b,
1867+ const struct crypto_bignum *c,
1868+ struct crypto_bignum *d)
1869+{
1870+ return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d,
1871+ (const mbedtls_mpi *)a,
1872+ (const mbedtls_mpi *)b)
1873+ || mbedtls_mpi_mod_mpi((mbedtls_mpi *)d,
1874+ (mbedtls_mpi *)d,
1875+ (const mbedtls_mpi *)c) ? -1 : 0;
1876+}
1877+
1878+int crypto_bignum_sqrmod(const struct crypto_bignum *a,
1879+ const struct crypto_bignum *b,
1880+ struct crypto_bignum *c)
1881+{
1882+ #if 1
1883+ return crypto_bignum_mulmod(a, a, b, c);
1884+ #else
1885+ mbedtls_mpi bn;
1886+ mbedtls_mpi_init(&bn);
1887+ if (mbedtls_mpi_lset(&bn, 2)) /* alt?: mbedtls_mpi_set_bit(&bn, 1) */
1888+ return -1;
1889+ int ret = mbedtls_mpi_exp_mod((mbedtls_mpi *)c,
1890+ (const mbedtls_mpi *)a, &bn,
1891+ (const mbedtls_mpi *)b, NULL) ? -1 : 0;
1892+ mbedtls_mpi_free(&bn);
1893+ return ret;
1894+ #endif
1895+}
1896+
1897+int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1898+ struct crypto_bignum *r)
1899+{
1900+ return mbedtls_mpi_copy((mbedtls_mpi *)r, (const mbedtls_mpi *)a)
1901+ || mbedtls_mpi_shift_r((mbedtls_mpi *)r, n) ? -1 : 0;
1902+}
1903+
1904+int crypto_bignum_cmp(const struct crypto_bignum *a,
1905+ const struct crypto_bignum *b)
1906+{
1907+ return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
1908+}
1909+
1910+int crypto_bignum_is_zero(const struct crypto_bignum *a)
1911+{
1912+ /* XXX: src/common/sae.c:sswu() contains comment:
1913+ * "TODO: Make sure crypto_bignum_is_zero() is constant time"
1914+ * Note: mbedtls_mpi_cmp_int() *is not* constant time */
1915+ return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 0) == 0);
1916+}
1917+
1918+int crypto_bignum_is_one(const struct crypto_bignum *a)
1919+{
1920+ return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 1) == 0);
1921+}
1922+
1923+int crypto_bignum_is_odd(const struct crypto_bignum *a)
1924+{
1925+ return mbedtls_mpi_get_bit((const mbedtls_mpi *)a, 0);
1926+}
1927+
1928+#include "utils/const_time.h"
1929+int crypto_bignum_legendre(const struct crypto_bignum *a,
1930+ const struct crypto_bignum *p)
1931+{
1932+ /* Security Note:
1933+ * mbedtls_mpi_exp_mod() is not documented to run in constant time,
1934+ * though mbedtls/library/bignum.c uses constant_time_internal.h funcs.
1935+ * Compare to crypto_openssl.c:crypto_bignum_legendre()
1936+ * which uses openssl BN_mod_exp_mont_consttime()
1937+ * mbedtls/library/ecp.c has further countermeasures to timing attacks,
1938+ * (but ecp.c funcs are not used here) */
1939+
1940+ mbedtls_mpi exp, tmp;
1941+ mbedtls_mpi_init(&exp);
1942+ mbedtls_mpi_init(&tmp);
1943+
1944+ /* exp = (p-1) / 2 */
1945+ int res;
1946+ if (mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *)p, 1) == 0
1947+ && mbedtls_mpi_shift_r(&exp, 1) == 0
1948+ && mbedtls_mpi_exp_mod(&tmp, (const mbedtls_mpi *)a, &exp,
1949+ (const mbedtls_mpi *)p, NULL) == 0) {
1950+ /*(modified from crypto_openssl.c:crypto_bignum_legendre())*/
1951+ /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need
1952+ * to use constant time selection to avoid branches here. */
1953+ unsigned int mask;
1954+ res = -1;
1955+ mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 1) == 0), 1);
1956+ res = const_time_select_int(mask, 1, res);
1957+ mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 0) == 0), 1);
1958+ res = const_time_select_int(mask, 0, res);
1959+ } else {
1960+ res = -2;
1961+ }
1962+
1963+ mbedtls_mpi_free(&tmp);
1964+ mbedtls_mpi_free(&exp);
1965+ return res;
1966+}
1967+
1968+#endif /* CRYPTO_MBEDTLS_CRYPTO_BIGNUM */
1969+
1970+
1971+#ifdef CRYPTO_MBEDTLS_CRYPTO_DH
1972+
1973+/* crypto_internal-modexp.c */
1974+
1975+#include <mbedtls/bignum.h>
1976+#include <mbedtls/dhm.h>
1977+
1978+#if 0 /* crypto_dh_init() and crypto_dh_derive_secret() prefer to use mbedtls */
1979+int crypto_mod_exp(const u8 *base, size_t base_len,
1980+ const u8 *power, size_t power_len,
1981+ const u8 *modulus, size_t modulus_len,
1982+ u8 *result, size_t *result_len)
1983+{
1984+ mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result;
1985+ mbedtls_mpi_init(&bn_base);
1986+ mbedtls_mpi_init(&bn_exp);
1987+ mbedtls_mpi_init(&bn_modulus);
1988+ mbedtls_mpi_init(&bn_result);
1989+
1990+ size_t len;
1991+ int ret = mbedtls_mpi_read_binary(&bn_base, base, base_len)
1992+ || mbedtls_mpi_read_binary(&bn_exp, power, power_len)
1993+ || mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len)
1994+ || mbedtls_mpi_exp_mod(&bn_result,&bn_base,&bn_exp,&bn_modulus,NULL)
1995+ || (len = mbedtls_mpi_size(&bn_result)) > *result_len
1996+ || mbedtls_mpi_write_binary(&bn_result, result, (*result_len = len))
1997+ ? -1
1998+ : 0;
1999+
2000+ mbedtls_mpi_free(&bn_base);
2001+ mbedtls_mpi_free(&bn_exp);
2002+ mbedtls_mpi_free(&bn_modulus);
2003+ mbedtls_mpi_free(&bn_result);
2004+ return ret;
2005+}
2006+#endif
2007+
2008+static int crypto_mbedtls_dh_set_bin_pg(mbedtls_dhm_context *ctx, u8 generator,
2009+ const u8 *prime, size_t prime_len)
2010+{
2011+ /*(could set these directly in MBEDTLS_PRIVATE members)*/
2012+ mbedtls_mpi P, G;
2013+ mbedtls_mpi_init(&P);
2014+ mbedtls_mpi_init(&G);
2015+ int ret = mbedtls_mpi_lset(&G, generator)
2016+ || mbedtls_mpi_read_binary(&P, prime, prime_len)
2017+ || mbedtls_dhm_set_group(ctx, &P, &G);
2018+ mbedtls_mpi_free(&P);
2019+ mbedtls_mpi_free(&G);
2020+ return ret;
2021+}
2022+
2023+__attribute_noinline__
2024+static int crypto_mbedtls_dh_init_public(mbedtls_dhm_context *ctx, u8 generator,
2025+ const u8 *prime, size_t prime_len,
2026+ u8 *privkey, u8 *pubkey)
2027+{
2028+ if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len)
2029+ || mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len,
2030+ mbedtls_ctr_drbg_random,
2031+ crypto_mbedtls_ctr_drbg()))
2032+ return -1;
2033+
2034+ /*(enable later when upstream mbedtls interface changes require)*/
2035+ #if 0 && MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
2036+ mbedtls_mpi X;
2037+ mbedtls_mpi_init(&X);
2038+ int ret = mbedtls_dhm_get_value(ctx, MBEDTLS_DHM_PARAM_X, &X)
2039+ || mbedtls_mpi_write_binary(&X, privkey, prime_len) ? -1 : 0;
2040+ mbedtls_mpi_free(&X);
2041+ return ret;
2042+ #else
2043+ return mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(X),
2044+ privkey, prime_len) ? -1 : 0;
2045+ #endif
2046+}
2047+
2048+int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
2049+ u8 *pubkey)
2050+{
2051+ #if 0 /*(crypto_dh_init() duplicated (and identical) in crypto_*.c modules)*/
2052+ size_t pubkey_len, pad;
2053+
2054+ if (os_get_random(privkey, prime_len) < 0)
2055+ return -1;
2056+ if (os_memcmp(privkey, prime, prime_len) > 0) {
2057+ /* Make sure private value is smaller than prime */
2058+ privkey[0] = 0;
2059+ }
2060+
2061+ pubkey_len = prime_len;
2062+ if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len,
2063+ pubkey, &pubkey_len) < 0)
2064+ return -1;
2065+ if (pubkey_len < prime_len) {
2066+ pad = prime_len - pubkey_len;
2067+ os_memmove(pubkey + pad, pubkey, pubkey_len);
2068+ os_memset(pubkey, 0, pad);
2069+ }
2070+
2071+ return 0;
2072+ #else
2073+ /* Prefer to use mbedtls to derive our public/private key, as doing so
2074+ * leverages mbedtls to properly format output and to perform blinding*/
2075+ mbedtls_dhm_context ctx;
2076+ mbedtls_dhm_init(&ctx);
2077+ int ret = crypto_mbedtls_dh_init_public(&ctx, generator, prime,
2078+ prime_len, privkey, pubkey);
2079+ mbedtls_dhm_free(&ctx);
2080+ return ret;
2081+ #endif
2082+}
2083+
2084+/*(crypto_dh_derive_secret() could be implemented using crypto.h APIs
2085+ * instead of being reimplemented in each crypto_*.c)*/
2086+int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len,
2087+ const u8 *order, size_t order_len,
2088+ const u8 *privkey, size_t privkey_len,
2089+ const u8 *pubkey, size_t pubkey_len,
2090+ u8 *secret, size_t *len)
2091+{
2092+ #if 0
2093+ if (pubkey_len > prime_len ||
2094+ (pubkey_len == prime_len &&
2095+ os_memcmp(pubkey, prime, prime_len) >= 0))
2096+ return -1;
2097+
2098+ int res = 0;
2099+ mbedtls_mpi pub;
2100+ mbedtls_mpi_init(&pub);
2101+ if (mbedtls_mpi_read_binary(&pub, pubkey, pubkey_len)
2102+ || mbedtls_mpi_cmp_int(&pub, 1) <= 0) {
2103+ res = -1;
2104+ } else if (order) {
2105+ mbedtls_mpi p, q, tmp;
2106+ mbedtls_mpi_init(&p);
2107+ mbedtls_mpi_init(&q);
2108+ mbedtls_mpi_init(&tmp);
2109+
2110+ /* verify: pubkey^q == 1 mod p */
2111+ res = (mbedtls_mpi_read_binary(&p, prime, prime_len)
2112+ || mbedtls_mpi_read_binary(&q, order, order_len)
2113+ || mbedtls_mpi_exp_mod(&tmp, &pub, &q, &p, NULL)
2114+ || mbedtls_mpi_cmp_int(&tmp, 1) != 0);
2115+
2116+ mbedtls_mpi_free(&p);
2117+ mbedtls_mpi_free(&q);
2118+ mbedtls_mpi_free(&tmp);
2119+ }
2120+ mbedtls_mpi_free(&pub);
2121+
2122+ return (res == 0)
2123+ ? crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len,
2124+ prime, prime_len, secret, len)
2125+ : -1;
2126+ #else
2127+ /* Prefer to use mbedtls to derive DH shared secret, as doing so
2128+ * leverages mbedtls to validate params and to perform blinding.
2129+ *
2130+ * Attempt to reconstitute DH context to derive shared secret
2131+ * (due to limitations of the interface, which ought to pass context).
2132+ * Force provided G (our private key) into context without validation.
2133+ * Regenerating GX (our public key) not needed to derive shared secret.
2134+ */
2135+ /*(older compilers might not support VLAs)*/
2136+ /*unsigned char buf[2+prime_len+2+1+2+pubkey_len];*/
2137+ unsigned char buf[2+MBEDTLS_MPI_MAX_SIZE+2+1+2+MBEDTLS_MPI_MAX_SIZE];
2138+ unsigned char *p = buf + 2 + prime_len;
2139+ if (2+prime_len+2+1+2+pubkey_len > sizeof(buf))
2140+ return -1;
2141+ WPA_PUT_BE16(buf, prime_len); /*(2-byte big-endian size of prime)*/
2142+ p[0] = 0; /*(2-byte big-endian size of generator)*/
2143+ p[1] = 1;
2144+ p[2] = generator;
2145+ WPA_PUT_BE16(p+3, pubkey_len); /*(2-byte big-endian size of pubkey)*/
2146+ os_memcpy(p+5, pubkey, pubkey_len);
2147+ os_memcpy(buf+2, prime, prime_len);
2148+
2149+ mbedtls_dhm_context ctx;
2150+ mbedtls_dhm_init(&ctx);
2151+ p = buf;
2152+ int ret = mbedtls_dhm_read_params(&ctx, &p, p+2+prime_len+5+pubkey_len)
2153+ || mbedtls_mpi_read_binary(&ctx.MBEDTLS_PRIVATE(X),
2154+ privkey, privkey_len)
2155+ || mbedtls_dhm_calc_secret(&ctx, secret, *len, len,
2156+ mbedtls_ctr_drbg_random,
2157+ crypto_mbedtls_ctr_drbg()) ? -1 : 0;
2158+ mbedtls_dhm_free(&ctx);
2159+ return ret;
2160+ #endif
2161+}
2162+
2163+/* dh_group5.c */
2164+
2165+#include "dh_group5.h"
2166+
2167+/* RFC3526_PRIME_1536[] and RFC3526_GENERATOR_1536[] from crypto_wolfssl.c */
2168+
2169+static const unsigned char RFC3526_PRIME_1536[] = {
2170+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
2171+ 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
2172+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
2173+ 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
2174+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
2175+ 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
2176+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
2177+ 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
2178+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
2179+ 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
2180+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
2181+ 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
2182+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
2183+ 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
2184+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
2185+ 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
2186+};
2187+
2188+static const unsigned char RFC3526_GENERATOR_1536[] = {
2189+ 0x02
2190+};
2191+
2192+void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
2193+{
2194+ const unsigned char * const prime = RFC3526_PRIME_1536;
2195+ const size_t prime_len = sizeof(RFC3526_PRIME_1536);
2196+ const u8 generator = *RFC3526_GENERATOR_1536;
2197+ struct wpabuf *wpubl = NULL, *wpriv = NULL;
2198+
2199+ mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx));
2200+ if (ctx == NULL)
2201+ return NULL;
2202+ mbedtls_dhm_init(ctx);
2203+
2204+ if ( (wpubl = wpabuf_alloc(prime_len))
2205+ && (wpriv = wpabuf_alloc(prime_len))
2206+ && crypto_mbedtls_dh_init_public(ctx, generator, prime, prime_len,
2207+ wpabuf_put(wpriv, prime_len),
2208+ wpabuf_put(wpubl, prime_len))==0) {
2209+ wpabuf_free(*publ);
2210+ wpabuf_clear_free(*priv);
2211+ *publ = wpubl;
2212+ *priv = wpriv;
2213+ return ctx;
2214+ }
2215+
2216+ wpabuf_clear_free(wpriv);
2217+ wpabuf_free(wpubl);
2218+ mbedtls_dhm_free(ctx);
2219+ os_free(ctx);
2220+ return NULL;
2221+}
2222+
2223+#ifdef CRYPTO_MBEDTLS_DH5_INIT_FIXED
2224+void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
2225+{
2226+ const unsigned char * const prime = RFC3526_PRIME_1536;
2227+ const size_t prime_len = sizeof(RFC3526_PRIME_1536);
2228+ const u8 generator = *RFC3526_GENERATOR_1536;
2229+
2230+ mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx));
2231+ if (ctx == NULL)
2232+ return NULL;
2233+ mbedtls_dhm_init(ctx);
2234+
2235+ if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len)==0
2236+ #if 0 /*(ignore; not required to derive shared secret)*/
2237+ && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(GX),
2238+ wpabuf_head(publ),wpabuf_len(publ))==0
2239+ #endif
2240+ && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(X),
2241+ wpabuf_head(priv),wpabuf_len(priv))==0) {
2242+ return ctx;
2243+ }
2244+
2245+ mbedtls_dhm_free(ctx);
2246+ os_free(ctx);
2247+ return NULL;
2248+}
2249+#endif
2250+
2251+struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
2252+ const struct wpabuf *own_private)
2253+{
2254+ /*((mbedtls_dhm_context *)ctx must already contain own_private)*/
2255+ /* mbedtls 2.x: prime_len = ctx->len; */
2256+ /* mbedtls 3.x: prime_len = mbedtls_dhm_get_len(ctx); */
2257+ size_t olen = sizeof(RFC3526_PRIME_1536); /*(sizeof(); prime known)*/
2258+ struct wpabuf *buf = wpabuf_alloc(olen);
2259+ if (buf == NULL)
2260+ return NULL;
2261+ if (mbedtls_dhm_read_public((mbedtls_dhm_context *)ctx,
2262+ wpabuf_head(peer_public),
2263+ wpabuf_len(peer_public)) == 0
2264+ && mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen,
2265+ mbedtls_ctr_drbg_random,
2266+ crypto_mbedtls_ctr_drbg()) == 0) {
2267+ wpabuf_put(buf, olen);
2268+ return buf;
2269+ }
2270+
2271+ wpabuf_free(buf);
2272+ return NULL;
2273+}
2274+
2275+void dh5_free(void *ctx)
2276+{
2277+ mbedtls_dhm_free(ctx);
2278+ os_free(ctx);
2279+}
2280+
2281+#endif /* CRYPTO_MBEDTLS_CRYPTO_DH */
2282+
2283+
2284+#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC)
2285+
2286+#include <mbedtls/ecp.h>
2287+
2288+#define CRYPTO_EC_pbits(e) (((mbedtls_ecp_group *)(e))->pbits)
2289+#define CRYPTO_EC_plen(e) ((((mbedtls_ecp_group *)(e))->pbits+7)>>3)
2290+#define CRYPTO_EC_P(e) (&((mbedtls_ecp_group *)(e))->P)
2291+#define CRYPTO_EC_N(e) (&((mbedtls_ecp_group *)(e))->N)
2292+#define CRYPTO_EC_A(e) (&((mbedtls_ecp_group *)(e))->A)
2293+#define CRYPTO_EC_B(e) (&((mbedtls_ecp_group *)(e))->B)
2294+#define CRYPTO_EC_G(e) (&((mbedtls_ecp_group *)(e))->G)
2295+
2296+static mbedtls_ecp_group_id crypto_mbedtls_ecp_group_id_from_ike_id(int group)
2297+{
2298+ /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */
2299+ switch (group) {
2300+ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
2301+ case 19: return MBEDTLS_ECP_DP_SECP256R1;
2302+ #endif
2303+ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
2304+ case 20: return MBEDTLS_ECP_DP_SECP384R1;
2305+ #endif
2306+ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
2307+ case 21: return MBEDTLS_ECP_DP_SECP521R1;
2308+ #endif
2309+ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED
2310+ case 25: return MBEDTLS_ECP_DP_SECP192R1;
2311+ #endif
2312+ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED
2313+ case 26: return MBEDTLS_ECP_DP_SECP224R1;
2314+ #endif
2315+ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED
2316+ case 28: return MBEDTLS_ECP_DP_BP256R1;
2317+ #endif
2318+ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED
2319+ case 29: return MBEDTLS_ECP_DP_BP384R1;
2320+ #endif
2321+ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED
2322+ case 30: return MBEDTLS_ECP_DP_BP512R1;
2323+ #endif
2324+ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
2325+ case 31: return MBEDTLS_ECP_DP_CURVE25519;
2326+ #endif
2327+ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
2328+ case 32: return MBEDTLS_ECP_DP_CURVE448;
2329+ #endif
2330+ default: return MBEDTLS_ECP_DP_NONE;
2331+ }
2332+}
2333+
2334+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC
2335+static int crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id)
2336+{
2337+ /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */
2338+ /*(for crypto_ec_key_group())*/
2339+ switch (grp_id) {
2340+ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
2341+ case MBEDTLS_ECP_DP_SECP256R1: return 19;
2342+ #endif
2343+ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
2344+ case MBEDTLS_ECP_DP_SECP384R1: return 20;
2345+ #endif
2346+ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
2347+ case MBEDTLS_ECP_DP_SECP521R1: return 21;
2348+ #endif
2349+ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED
2350+ case MBEDTLS_ECP_DP_SECP192R1: return 25;
2351+ #endif
2352+ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED
2353+ case MBEDTLS_ECP_DP_SECP224R1: return 26;
2354+ #endif
2355+ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED
2356+ case MBEDTLS_ECP_DP_BP256R1: return 28;
2357+ #endif
2358+ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED
2359+ case MBEDTLS_ECP_DP_BP384R1: return 29;
2360+ #endif
2361+ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED
2362+ case MBEDTLS_ECP_DP_BP512R1: return 30;
2363+ #endif
2364+ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
2365+ case MBEDTLS_ECP_DP_CURVE25519: return 31;
2366+ #endif
2367+ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
2368+ case MBEDTLS_ECP_DP_CURVE448: return 32;
2369+ #endif
2370+ default: return -1;
2371+ }
2372+}
2373+#endif
2374+
2375+#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH || CRYPTO_MBEDTLS_CRYPTO_EC */
2376+
2377+
2378+#if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC_DPP)
2379+
2380+#include <mbedtls/ecp.h>
2381+#include <mbedtls/pk.h>
2382+
2383+static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk)
2384+{
2385+ mbedtls_ecp_group_id grp_id =
2386+ crypto_mbedtls_ecp_group_id_from_ike_id(group);
2387+ if (grp_id == MBEDTLS_ECP_DP_NONE)
2388+ return -1;
2389+ const mbedtls_pk_info_t *pk_info =
2390+ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
2391+ if (pk_info == NULL)
2392+ return -1;
2393+ return mbedtls_pk_setup(pk, pk_info)
2394+ || mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk),
2395+ mbedtls_ctr_drbg_random,
2396+ crypto_mbedtls_ctr_drbg()) ? -1 : 0;
2397+}
2398+
2399+#endif
2400+
2401+
2402+#ifdef CRYPTO_MBEDTLS_CRYPTO_ECDH
2403+
2404+#include <mbedtls/ecdh.h>
2405+#include <mbedtls/ecdsa.h>
2406+#include <mbedtls/ecp.h>
2407+#include <mbedtls/pk.h>
2408+
2409+/* wrap mbedtls_ecdh_context for more future-proof direct access to components
2410+ * (mbedtls_ecdh_context internal implementation may change between releases)
2411+ *
2412+ * If mbedtls_pk_context -- specifically underlying mbedtls_ecp_keypair --
2413+ * lifetime were guaranteed to be longer than that of mbedtls_ecdh_context,
2414+ * then mbedtls_pk_context or mbedtls_ecp_keypair could be stored in crypto_ecdh
2415+ * (or crypto_ec_key could be stored in crypto_ecdh, and crypto_ec_key could
2416+ * wrap mbedtls_ecp_keypair and components, to avoid MBEDTLS_PRIVATE access) */
2417+struct crypto_ecdh {
2418+ mbedtls_ecdh_context ctx;
2419+ mbedtls_ecp_group grp;
2420+ mbedtls_ecp_point Q;
2421+};
2422+
2423+struct crypto_ecdh * crypto_ecdh_init(int group)
2424+{
2425+ mbedtls_pk_context pk;
2426+ mbedtls_pk_init(&pk);
2427+ struct crypto_ecdh *ecdh = crypto_mbedtls_keypair_gen(group, &pk) == 0
2428+ ? crypto_ecdh_init2(group, (struct crypto_ec_key *)&pk)
2429+ : NULL;
2430+ mbedtls_pk_free(&pk);
2431+ return ecdh;
2432+}
2433+
2434+struct crypto_ecdh * crypto_ecdh_init2(int group,
2435+ struct crypto_ec_key *own_key)
2436+{
2437+ mbedtls_ecp_group_id grp_id =
2438+ crypto_mbedtls_ecp_group_id_from_ike_id(group);
2439+ if (grp_id == MBEDTLS_ECP_DP_NONE)
2440+ return NULL;
2441+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)own_key);
2442+ struct crypto_ecdh *ecdh = os_malloc(sizeof(*ecdh));
2443+ if (ecdh == NULL)
2444+ return NULL;
2445+ mbedtls_ecdh_init(&ecdh->ctx);
2446+ mbedtls_ecp_group_init(&ecdh->grp);
2447+ mbedtls_ecp_point_init(&ecdh->Q);
2448+ if (mbedtls_ecdh_setup(&ecdh->ctx, grp_id) == 0
2449+ && mbedtls_ecdh_get_params(&ecdh->ctx,ecp_kp,MBEDTLS_ECDH_OURS) == 0) {
2450+ /* copy grp and Q for later use
2451+ * (retrieving this info later is more convoluted
2452+ * even if mbedtls_ecdh_make_public() is considered)*/
2453+ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */
2454+ mbedtls_mpi d;
2455+ mbedtls_mpi_init(&d);
2456+ if (mbedtls_ecp_export(ecp_kp, &ecdh->grp, &d, &ecdh->Q) == 0) {
2457+ mbedtls_mpi_free(&d);
2458+ return ecdh;
2459+ }
2460+ mbedtls_mpi_free(&d);
2461+ #else
2462+ if (mbedtls_ecp_group_load(&ecdh->grp, grp_id) == 0
2463+ && mbedtls_ecp_copy(&ecdh->Q, &ecp_kp->MBEDTLS_PRIVATE(Q)) == 0)
2464+ return ecdh;
2465+ #endif
2466+ }
2467+
2468+ mbedtls_ecp_point_free(&ecdh->Q);
2469+ mbedtls_ecp_group_free(&ecdh->grp);
2470+ mbedtls_ecdh_free(&ecdh->ctx);
2471+ os_free(ecdh);
2472+ return NULL;
2473+}
2474+
2475+struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
2476+{
2477+ mbedtls_ecp_group *grp = &ecdh->grp;
2478+ size_t len = CRYPTO_EC_plen(grp);
2479+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
2480+ /* len */
2481+ #endif
2482+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
2483+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS)
2484+ len = inc_y ? len*2+1 : len+1;
2485+ #endif
2486+ struct wpabuf *buf = wpabuf_alloc(len);
2487+ if (buf == NULL)
2488+ return NULL;
2489+ inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED;
2490+ if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &len,
2491+ wpabuf_mhead_u8(buf), len) == 0) {
2492+ wpabuf_put(buf, len);
2493+ return buf;
2494+ }
2495+
2496+ wpabuf_free(buf);
2497+ return NULL;
2498+}
2499+
2500+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
2501+static int crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group *grp,
2502+ mbedtls_mpi *bn,
2503+ int parity_bit)
2504+{
2505+ /* y^2 = x^3 + ax + b
2506+ * sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */
2507+ mbedtls_mpi *cy2 = (mbedtls_mpi *)
2508+ crypto_ec_point_compute_y_sqr((struct crypto_ec *)grp,
2509+ (const struct crypto_bignum *)bn); /*x*/
2510+ if (cy2 == NULL)
2511+ return -1;
2512+
2513+ /*mbedtls_mpi_free(bn);*/
2514+ /*(reuse bn to store result (y))*/
2515+
2516+ mbedtls_mpi exp;
2517+ mbedtls_mpi_init(&exp);
2518+ int ret = mbedtls_mpi_get_bit(&grp->P, 0) != 1 /*(p = 3 mod 4)*/
2519+ || mbedtls_mpi_get_bit(&grp->P, 1) != 1 /*(p = 3 mod 4)*/
2520+ || mbedtls_mpi_add_int(&exp, &grp->P, 1)
2521+ || mbedtls_mpi_shift_r(&exp, 2)
2522+ || mbedtls_mpi_exp_mod(bn, cy2, &exp, &grp->P, NULL)
2523+ || (mbedtls_mpi_get_bit(bn, 0) != parity_bit
2524+ && mbedtls_mpi_sub_mpi(bn, &grp->P, bn));
2525+ mbedtls_mpi_free(&exp);
2526+ mbedtls_mpi_free(cy2);
2527+ os_free(cy2);
2528+ return ret;
2529+}
2530+#endif
2531+
2532+struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
2533+ const u8 *key, size_t len)
2534+{
2535+ if (len == 0) /*(invalid peer key)*/
2536+ return NULL;
2537+
2538+ mbedtls_ecp_group *grp = &ecdh->grp;
2539+
2540+ #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
2541+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
2542+ /* add header for mbedtls_ecdh_read_public() */
2543+ u8 buf[256];
2544+ if (sizeof(buf)-1 < len)
2545+ return NULL;
2546+ buf[0] = (u8)(len);
2547+ os_memcpy(buf+1, key, len);
2548+
2549+ if (inc_y) {
2550+ if (!(len & 1)) { /*(dpp code/tests does not include tag?!?)*/
2551+ if (sizeof(buf)-2 < len)
2552+ return NULL;
2553+ buf[0] = (u8)(1+len);
2554+ buf[1] = 0x04;
2555+ os_memcpy(buf+2, key, len);
2556+ }
2557+ len >>= 1; /*(repurpose len to prime_len)*/
2558+ }
2559+ else if (key[0] == 0x02 || key[0] == 0x03) { /* (inc_y == 0) */
2560+ --len; /*(repurpose len to prime_len)*/
2561+
2562+ /* mbedtls_ecp_point_read_binary() does not currently support
2563+ * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03)
2564+ * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */
2565+
2566+ /* derive y, amend buf[] with y for UNCOMPRESSED format */
2567+ if (sizeof(buf)-2 < len*2 || len == 0)
2568+ return NULL;
2569+ buf[0] = (u8)(1+len*2);
2570+ buf[1] = 0x04;
2571+ mbedtls_mpi bn;
2572+ mbedtls_mpi_init(&bn);
2573+ int ret = mbedtls_mpi_read_binary(&bn, key+1, len)
2574+ || crypto_mbedtls_short_weierstrass_derive_y(grp, &bn,
2575+ key[0] & 1)
2576+ || mbedtls_mpi_write_binary(&bn, buf+2+len, len);
2577+ mbedtls_mpi_free(&bn);
2578+ if (ret != 0)
2579+ return NULL;
2580+ }
2581+
2582+ if (key[0] == 0) /*(repurpose len to prime_len)*/
2583+ len = CRYPTO_EC_plen(grp);
2584+
2585+ if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0]+1))
2586+ return NULL;
2587+ }
2588+ #endif
2589+ #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
2590+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
2591+ if (mbedtls_ecdh_read_public(&ecdh->ctx, key, len))
2592+ return NULL;
2593+ }
2594+ #endif
2595+
2596+ struct wpabuf *buf = wpabuf_alloc(len);
2597+ if (buf == NULL)
2598+ return NULL;
2599+
2600+ if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len,
2601+ wpabuf_mhead(buf), len,
2602+ mbedtls_ctr_drbg_random,
2603+ crypto_mbedtls_ctr_drbg()) == 0) {
2604+ wpabuf_put(buf, len);
2605+ return buf;
2606+ }
2607+
2608+ wpabuf_clear_free(buf);
2609+ return NULL;
2610+}
2611+
2612+void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
2613+{
2614+ if (ecdh == NULL)
2615+ return;
2616+ mbedtls_ecp_point_free(&ecdh->Q);
2617+ mbedtls_ecp_group_free(&ecdh->grp);
2618+ mbedtls_ecdh_free(&ecdh->ctx);
2619+ os_free(ecdh);
2620+}
2621+
2622+size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
2623+{
2624+ return CRYPTO_EC_plen(&ecdh->grp);
2625+}
2626+
2627+#endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH */
2628+
2629+
2630+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC
2631+
2632+#include <mbedtls/ecp.h>
2633+
2634+struct crypto_ec *crypto_ec_init(int group)
2635+{
2636+ mbedtls_ecp_group_id grp_id =
2637+ crypto_mbedtls_ecp_group_id_from_ike_id(group);
2638+ if (grp_id == MBEDTLS_ECP_DP_NONE)
2639+ return NULL;
2640+ mbedtls_ecp_group *e = os_malloc(sizeof(*e));
2641+ if (e == NULL)
2642+ return NULL;
2643+ mbedtls_ecp_group_init(e);
2644+ if (mbedtls_ecp_group_load(e, grp_id) == 0)
2645+ return (struct crypto_ec *)e;
2646+
2647+ mbedtls_ecp_group_free(e);
2648+ os_free(e);
2649+ return NULL;
2650+}
2651+
2652+void crypto_ec_deinit(struct crypto_ec *e)
2653+{
2654+ mbedtls_ecp_group_free((mbedtls_ecp_group *)e);
2655+ os_free(e);
2656+}
2657+
2658+size_t crypto_ec_prime_len(struct crypto_ec *e)
2659+{
2660+ return CRYPTO_EC_plen(e);
2661+}
2662+
2663+size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
2664+{
2665+ return CRYPTO_EC_pbits(e);
2666+}
2667+
2668+size_t crypto_ec_order_len(struct crypto_ec *e)
2669+{
2670+ return (mbedtls_mpi_bitlen(CRYPTO_EC_N(e)) + 7) / 8;
2671+}
2672+
2673+const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e)
2674+{
2675+ return (const struct crypto_bignum *)CRYPTO_EC_P(e);
2676+}
2677+
2678+const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e)
2679+{
2680+ return (const struct crypto_bignum *)CRYPTO_EC_N(e);
2681+}
2682+
2683+const struct crypto_bignum *crypto_ec_get_a(struct crypto_ec *e)
2684+{
2685+ static const uint8_t secp256r1_a[] =
2686+ {0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x01,
2687+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2688+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
2689+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc};
2690+ static const uint8_t secp384r1_a[] =
2691+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2692+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2693+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2694+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
2695+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
2696+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xfc};
2697+ static const uint8_t secp521r1_a[] =
2698+ {0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2699+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2700+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2701+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2702+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2703+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2704+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2705+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2706+ 0xff,0xfc};
2707+ static const uint8_t secp192r1_a[] =
2708+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2709+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
2710+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc};
2711+ static const uint8_t secp224r1_a[] =
2712+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2713+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
2714+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
2715+ 0xff,0xff,0xff,0xfe};
2716+
2717+ const uint8_t *bin = NULL;
2718+ size_t len = 0;
2719+
2720+ /* (mbedtls groups matching supported sswu_curve_param() IKE groups) */
2721+ switch (((mbedtls_ecp_group *)e)->id) {
2722+ #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
2723+ case MBEDTLS_ECP_DP_SECP256R1:
2724+ bin = secp256r1_a;
2725+ len = sizeof(secp256r1_a);
2726+ break;
2727+ #endif
2728+ #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
2729+ case MBEDTLS_ECP_DP_SECP384R1:
2730+ bin = secp384r1_a;
2731+ len = sizeof(secp384r1_a);
2732+ break;
2733+ #endif
2734+ #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
2735+ case MBEDTLS_ECP_DP_SECP521R1:
2736+ bin = secp521r1_a;
2737+ len = sizeof(secp521r1_a);
2738+ break;
2739+ #endif
2740+ #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED
2741+ case MBEDTLS_ECP_DP_SECP192R1:
2742+ bin = secp192r1_a;
2743+ len = sizeof(secp192r1_a);
2744+ break;
2745+ #endif
2746+ #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED
2747+ case MBEDTLS_ECP_DP_SECP224R1:
2748+ bin = secp224r1_a;
2749+ len = sizeof(secp224r1_a);
2750+ break;
2751+ #endif
2752+ #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED
2753+ case MBEDTLS_ECP_DP_BP256R1:
2754+ return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2755+ #endif
2756+ #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED
2757+ case MBEDTLS_ECP_DP_BP384R1:
2758+ return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2759+ #endif
2760+ #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED
2761+ case MBEDTLS_ECP_DP_BP512R1:
2762+ return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2763+ #endif
2764+ #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
2765+ case MBEDTLS_ECP_DP_CURVE25519:
2766+ return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2767+ #endif
2768+ #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
2769+ case MBEDTLS_ECP_DP_CURVE448:
2770+ return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2771+ #endif
2772+ default:
2773+ return NULL;
2774+ }
2775+
2776+ /*(note: not thread-safe; returns file-scoped static storage)*/
2777+ if (mbedtls_mpi_read_binary(&mpi_sw_A, bin, len) == 0)
2778+ return (const struct crypto_bignum *)&mpi_sw_A;
2779+ return NULL;
2780+}
2781+
2782+const struct crypto_bignum *crypto_ec_get_b(struct crypto_ec *e)
2783+{
2784+ return (const struct crypto_bignum *)CRYPTO_EC_B(e);
2785+}
2786+
2787+const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
2788+{
2789+ return (const struct crypto_ec_point *)CRYPTO_EC_G(e);
2790+}
2791+
2792+struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e)
2793+{
2794+ mbedtls_ecp_point *p = os_malloc(sizeof(*p));
2795+ if (p != NULL)
2796+ mbedtls_ecp_point_init(p);
2797+ return (struct crypto_ec_point *)p;
2798+}
2799+
2800+void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
2801+{
2802+ mbedtls_ecp_point_free((mbedtls_ecp_point *)p);
2803+ os_free(p);
2804+}
2805+
2806+int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
2807+ struct crypto_bignum *x)
2808+{
2809+ mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X);
2810+ return mbedtls_mpi_copy((mbedtls_mpi *)x, px)
2811+ ? -1
2812+ : 0;
2813+}
2814+
2815+int crypto_ec_point_to_bin(struct crypto_ec *e,
2816+ const struct crypto_ec_point *point, u8 *x, u8 *y)
2817+{
2818+ /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */
2819+ size_t len = CRYPTO_EC_plen(e);
2820+ if (x) {
2821+ mbedtls_mpi *px = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(X);
2822+ if (mbedtls_mpi_write_binary(px, x, len))
2823+ return -1;
2824+ }
2825+ if (y) {
2826+ #if 0 /*(should not be necessary; py mpi should be in initial state)*/
2827+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
2828+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e)
2829+ == MBEDTLS_ECP_TYPE_MONTGOMERY) {
2830+ os_memset(y, 0, len);
2831+ return 0;
2832+ }
2833+ #endif
2834+ #endif
2835+ mbedtls_mpi *py = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(Y);
2836+ if (mbedtls_mpi_write_binary(py, y, len))
2837+ return -1;
2838+ }
2839+ return 0;
2840+}
2841+
2842+struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
2843+ const u8 *val)
2844+{
2845+ size_t len = CRYPTO_EC_plen(e);
2846+ mbedtls_ecp_point *p = os_malloc(sizeof(*p));
2847+ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2];
2848+ if (p == NULL)
2849+ return NULL;
2850+ mbedtls_ecp_point_init(p);
2851+
2852+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
2853+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e)
2854+ == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
2855+ #if 0 /* prefer alternative to MBEDTLS_PRIVATE() access */
2856+ mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X);
2857+ mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y);
2858+ mbedtls_mpi *pz = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Z);
2859+
2860+ if (mbedtls_mpi_read_binary(px, val, len) == 0
2861+ && mbedtls_mpi_read_binary(py, val + len, len) == 0
2862+ && mbedtls_mpi_lset(pz, 1) == 0)
2863+ return (struct crypto_ec_point *)p;
2864+ #else
2865+ buf[0] = 0x04;
2866+ os_memcpy(buf+1, val, len*2);
2867+ if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p,
2868+ buf, 1+len*2) == 0)
2869+ return (struct crypto_ec_point *)p;
2870+ #endif
2871+ }
2872+ #endif
2873+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
2874+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e)
2875+ == MBEDTLS_ECP_TYPE_MONTGOMERY) {
2876+ /* crypto.h interface documents crypto_ec_point_from_bin()
2877+ * val is length: prime_len * 2 and is big-endian
2878+ * (Short Weierstrass is assumed by hostap)
2879+ * Reverse to little-endian format for Montgomery */
2880+ for (unsigned int i = 0; i < len; ++i)
2881+ buf[i] = val[len-1-i];
2882+ if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p,
2883+ buf, len) == 0)
2884+ return (struct crypto_ec_point *)p;
2885+ }
2886+ #endif
2887+
2888+ mbedtls_ecp_point_free(p);
2889+ os_free(p);
2890+ return NULL;
2891+}
2892+
2893+int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
2894+ const struct crypto_ec_point *b,
2895+ struct crypto_ec_point *c)
2896+{
2897+ /* mbedtls does not provide an mbedtls_ecp_point add function */
2898+ mbedtls_mpi one;
2899+ mbedtls_mpi_init(&one);
2900+ int ret = mbedtls_mpi_lset(&one, 1)
2901+ || mbedtls_ecp_muladd(
2902+ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)c,
2903+ &one, (const mbedtls_ecp_point *)a,
2904+ &one, (const mbedtls_ecp_point *)b) ? -1 : 0;
2905+ mbedtls_mpi_free(&one);
2906+ return ret;
2907+}
2908+
2909+int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
2910+ const struct crypto_bignum *b,
2911+ struct crypto_ec_point *res)
2912+{
2913+ return mbedtls_ecp_mul(
2914+ (mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res,
2915+ (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p,
2916+ mbedtls_ctr_drbg_random, crypto_mbedtls_ctr_drbg()) ? -1 : 0;
2917+}
2918+
2919+int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
2920+{
2921+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e)
2922+ == MBEDTLS_ECP_TYPE_MONTGOMERY) {
2923+ /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */
2924+ wpa_printf(MSG_ERROR,
2925+ "%s not implemented for Montgomery curves",__func__);
2926+ return -1;
2927+ }
2928+
2929+ /* mbedtls does not provide an mbedtls_ecp_point invert function */
2930+ /* below works for Short Weierstrass; incorrect for Montgomery curves */
2931+ mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y);
2932+ return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p) /*point at infinity*/
2933+ || mbedtls_mpi_cmp_int(py, 0) == 0 /*point is its own inverse*/
2934+ || mbedtls_mpi_sub_abs(py, CRYPTO_EC_P(e), py) == 0 ? 0 : -1;
2935+}
2936+
2937+#ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
2938+static int
2939+crypto_ec_point_y_sqr_weierstrass(mbedtls_ecp_group *e, const mbedtls_mpi *x,
2940+ mbedtls_mpi *y2)
2941+{
2942+ /* MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS y^2 = x^3 + a x + b */
2943+
2944+ /* Short Weierstrass elliptic curve group w/o A set treated as A = -3 */
2945+ /* Attempt to match mbedtls/library/ecp.c:ecp_check_pubkey_sw() behavior
2946+ * and elsewhere in mbedtls/library/ecp.c where if A is not set, it is
2947+ * treated as if A = -3. */
2948+
2949+ #if 0
2950+ /* y^2 = x^3 + ax + b */
2951+ mbedtls_mpi *A = &e->A;
2952+ mbedtls_mpi t, A_neg3;
2953+ if (&e->A.p == NULL) {
2954+ mbedtls_mpi_init(&A_neg3);
2955+ if (mbedtls_mpi_lset(&A_neg3, -3) != 0) {
2956+ mbedtls_mpi_free(&A_neg3);
2957+ return -1;
2958+ }
2959+ A = &A_neg3;
2960+ }
2961+ mbedtls_mpi_init(&t);
2962+ int ret = /* x^3 */
2963+ mbedtls_mpi_lset(&t, 3)
2964+ || mbedtls_mpi_exp_mod(y2, x, &t, &e->P, NULL)
2965+ /* ax */
2966+ || mbedtls_mpi_mul_mpi(y2, y2, A)
2967+ || mbedtls_mpi_mod_mpi(&t, &t, &e->P)
2968+ /* ax + b */
2969+ || mbedtls_mpi_add_mpi(&t, &t, &e->B)
2970+ || mbedtls_mpi_mod_mpi(&t, &t, &e->P)
2971+ /* x^3 + ax + b */
2972+ || mbedtls_mpi_add_mpi(&t, &t, y2) /* ax + b + x^3 */
2973+ || mbedtls_mpi_mod_mpi(y2, &t, &e->P);
2974+ mbedtls_mpi_free(&t);
2975+ if (A == &A_neg3)
2976+ mbedtls_mpi_free(&A_neg3);
2977+ return ret; /* 0: success, non-zero: failure */
2978+ #else
2979+ /* y^2 = x^3 + ax + b = (x^2 + a)x + b */
2980+ return /* x^2 */
2981+ mbedtls_mpi_mul_mpi(y2, x, x)
2982+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P)
2983+ /* x^2 + a */
2984+ || (e->A.MBEDTLS_PRIVATE(p)
2985+ ? mbedtls_mpi_add_mpi(y2, y2, &e->A)
2986+ : mbedtls_mpi_sub_int(y2, y2, 3))
2987+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P)
2988+ /* (x^2 + a)x */
2989+ || mbedtls_mpi_mul_mpi(y2, y2, x)
2990+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P)
2991+ /* (x^2 + a)x + b */
2992+ || mbedtls_mpi_add_mpi(y2, y2, &e->B)
2993+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P);
2994+ #endif
2995+}
2996+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
2997+
2998+#if 0 /* not used by hostap */
2999+#ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
3000+static int
3001+crypto_ec_point_y_sqr_montgomery(mbedtls_ecp_group *e, const mbedtls_mpi *x,
3002+ mbedtls_mpi *y2)
3003+{
3004+ /* XXX: !!! must be reviewed and audited for correctness !!! */
3005+
3006+ /* MBEDTLS_ECP_TYPE_MONTGOMERY y^2 = x^3 + a x^2 + x */
3007+
3008+ /* y^2 = x^3 + a x^2 + x = (x + a)x^2 + x */
3009+ mbedtls_mpi x2;
3010+ mbedtls_mpi_init(&x2);
3011+ int ret = /* x^2 */
3012+ mbedtls_mpi_mul_mpi(&x2, x, x)
3013+ || mbedtls_mpi_mod_mpi(&x2, &x2, &e->P)
3014+ /* x + a */
3015+ || mbedtls_mpi_add_mpi(y2, x, &e->A)
3016+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P)
3017+ /* (x + a)x^2 */
3018+ || mbedtls_mpi_mul_mpi(y2, y2, &x2)
3019+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P)
3020+ /* (x + a)x^2 + x */
3021+ || mbedtls_mpi_add_mpi(y2, y2, x)
3022+ || mbedtls_mpi_mod_mpi(y2, y2, &e->P);
3023+ mbedtls_mpi_free(&x2);
3024+ return ret; /* 0: success, non-zero: failure */
3025+}
3026+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
3027+#endif
3028+
3029+struct crypto_bignum *
3030+crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
3031+ const struct crypto_bignum *x)
3032+{
3033+ mbedtls_mpi *y2 = os_malloc(sizeof(*y2));
3034+ if (y2 == NULL)
3035+ return NULL;
3036+ mbedtls_mpi_init(y2);
3037+
3038+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
3039+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e)
3040+ == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS
3041+ && crypto_ec_point_y_sqr_weierstrass((mbedtls_ecp_group *)e,
3042+ (const mbedtls_mpi *)x,
3043+ y2) == 0)
3044+ return (struct crypto_bignum *)y2;
3045+ #endif
3046+ #if 0 /* not used by hostap */
3047+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
3048+ if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e)
3049+ == MBEDTLS_ECP_TYPE_MONTGOMERY
3050+ && crypto_ec_point_y_sqr_montgomery((mbedtls_ecp_group *)e,
3051+ (const mbedtls_mpi *)x,
3052+ y2) == 0)
3053+ return (struct crypto_bignum *)y2;
3054+ #endif
3055+ #endif
3056+
3057+ mbedtls_mpi_free(y2);
3058+ os_free(y2);
3059+ return NULL;
3060+}
3061+
3062+int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
3063+ const struct crypto_ec_point *p)
3064+{
3065+ return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p);
3066+}
3067+
3068+int crypto_ec_point_is_on_curve(struct crypto_ec *e,
3069+ const struct crypto_ec_point *p)
3070+{
3071+ #if 1
3072+ return mbedtls_ecp_check_pubkey((const mbedtls_ecp_group *)e,
3073+ (const mbedtls_ecp_point *)p) == 0;
3074+ #else
3075+ /* compute y^2 mod P and compare to y^2 mod P */
3076+ /*(ref: src/eap_common/eap_pwd_common.c:compute_password_element())*/
3077+ const mbedtls_mpi *px = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X);
3078+ mbedtls_mpi *cy2 = (mbedtls_mpi *)
3079+ crypto_ec_point_compute_y_sqr(e, (const struct crypto_bignum *)px);
3080+ if (cy2 == NULL)
3081+ return 0;
3082+
3083+ mbedtls_mpi y2;
3084+ mbedtls_mpi_init(&y2);
3085+ const mbedtls_mpi *py = &((const mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y);
3086+ int is_on_curve = mbedtls_mpi_mul_mpi(&y2, py, py) /* y^2 mod P */
3087+ || mbedtls_mpi_mod_mpi(&y2, &y2, CRYPTO_EC_P(e))
3088+ || mbedtls_mpi_cmp_mpi(&y2, cy2) != 0 ? 0 : 1;
3089+
3090+ mbedtls_mpi_free(&y2);
3091+ mbedtls_mpi_free(cy2);
3092+ os_free(cy2);
3093+ return is_on_curve;
3094+ #endif
3095+}
3096+
3097+int crypto_ec_point_cmp(const struct crypto_ec *e,
3098+ const struct crypto_ec_point *a,
3099+ const struct crypto_ec_point *b)
3100+{
3101+ return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *)a,
3102+ (const mbedtls_ecp_point *)b);
3103+}
3104+
3105+#if !defined(CONFIG_NO_STDOUT_DEBUG)
3106+void crypto_ec_point_debug_print(const struct crypto_ec *e,
3107+ const struct crypto_ec_point *p,
3108+ const char *title)
3109+{
3110+ u8 x[MBEDTLS_MPI_MAX_SIZE];
3111+ u8 y[MBEDTLS_MPI_MAX_SIZE];
3112+ size_t len = CRYPTO_EC_plen(e);
3113+ /* crypto_ec_point_to_bin ought to take (const struct crypto_ec *e) */
3114+ struct crypto_ec *ee;
3115+ *(const struct crypto_ec **)&ee = e; /*(cast away const)*/
3116+ if (crypto_ec_point_to_bin(ee, p, x, y) == 0) {
3117+ if (title)
3118+ wpa_printf(MSG_DEBUG, "%s", title);
3119+ wpa_hexdump(MSG_DEBUG, "x:", x, len);
3120+ wpa_hexdump(MSG_DEBUG, "y:", y, len);
3121+ }
3122+}
3123+#endif
3124+
3125+
3126+struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
3127+{
3128+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
3129+ if (ctx == NULL)
3130+ return NULL;
3131+ mbedtls_pk_init(ctx);
3132+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
3133+ if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0) == 0)
3134+ #else
3135+ if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0,
3136+ mbedtls_ctr_drbg_random,
3137+ crypto_mbedtls_ctr_drbg()) == 0)
3138+ #endif
3139+ return (struct crypto_ec_key *)ctx;
3140+
3141+ mbedtls_pk_free(ctx);
3142+ os_free(ctx);
3143+ return NULL;
3144+}
3145+
3146+#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE
3147+#ifdef CONFIG_MODULE_TESTS
3148+/*(for crypto_module_tests.c)*/
3149+struct crypto_ec_key * crypto_ec_key_set_priv(int group,
3150+ const u8 *raw, size_t raw_len)
3151+{
3152+ mbedtls_ecp_group_id grp_id =
3153+ crypto_mbedtls_ecp_group_id_from_ike_id(group);
3154+ if (grp_id == MBEDTLS_ECP_DP_NONE)
3155+ return NULL;
3156+ const mbedtls_pk_info_t *pk_info =
3157+ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
3158+ if (pk_info == NULL)
3159+ return NULL;
3160+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
3161+ if (ctx == NULL)
3162+ return NULL;
3163+ mbedtls_pk_init(ctx);
3164+ if (mbedtls_pk_setup(ctx, pk_info) == 0
3165+ && mbedtls_ecp_read_key(grp_id,mbedtls_pk_ec(*ctx),raw,raw_len) == 0) {
3166+ return (struct crypto_ec_key *)ctx;
3167+ }
3168+
3169+ mbedtls_pk_free(ctx);
3170+ os_free(ctx);
3171+ return NULL;
3172+}
3173+#endif
3174+#endif
3175+
3176+#include <mbedtls/error.h>
3177+#include <mbedtls/oid.h>
3178+static int crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context *ctx, const u8 *der, size_t der_len)
3179+{
3180+ /* The following is modified from:
3181+ * mbedtls/library/pkparse.c:mbedtls_pk_parse_subpubkey()
3182+ * mbedtls/library/pkparse.c:pk_get_pk_alg()
3183+ * mbedtls/library/pkparse.c:pk_use_ecparams()
3184+ */
3185+ mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
3186+ const mbedtls_pk_info_t *pk_info;
3187+ int ret;
3188+ size_t len;
3189+ const unsigned char *end = der+der_len;
3190+ unsigned char *p;
3191+ *(const unsigned char **)&p = der;
3192+
3193+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
3194+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
3195+ {
3196+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
3197+ }
3198+
3199+ end = p + len;
3200+
3201+ /*
3202+ if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 )
3203+ return( ret );
3204+ */
3205+ mbedtls_asn1_buf alg_oid, params;
3206+ memset( &params, 0, sizeof(mbedtls_asn1_buf) );
3207+ if( ( ret = mbedtls_asn1_get_alg( &p, end, &alg_oid, &params ) ) != 0 )
3208+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_ALG, ret ) );
3209+ if( mbedtls_oid_get_pk_alg( &alg_oid, &pk_alg ) != 0 )
3210+ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
3211+
3212+ if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end, &len ) ) != 0 )
3213+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
3214+
3215+ if( p + len != end )
3216+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
3217+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
3218+
3219+ if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
3220+ return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
3221+
3222+ if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
3223+ return( ret );
3224+
3225+ /* assume mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx)
3226+ * has already run with ctx initialized up to pk_get_ecpubkey(),
3227+ * and pk_get_ecpubkey() has returned MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
3228+ *
3229+ * mbedtls mbedtls_ecp_point_read_binary()
3230+ * does not handle point in COMPRESSED format
3231+ *
3232+ * (validate assumption that algorithm is EC) */
3233+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx);
3234+ if (ecp_kp == NULL)
3235+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
3236+ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
3237+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
3238+ mbedtls_ecp_group_id grp_id;
3239+
3240+
3241+ /* mbedtls/library/pkparse.c:pk_use_ecparams() */
3242+
3243+ if( params.tag == MBEDTLS_ASN1_OID )
3244+ {
3245+ if( mbedtls_oid_get_ec_grp( &params, &grp_id ) != 0 )
3246+ return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE );
3247+ }
3248+ else
3249+ {
3250+#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
3251+ /*(large code block not copied from mbedtls; unsupported)*/
3252+ #if 0
3253+ if( ( ret = pk_group_id_from_specified( &params, &grp_id ) ) != 0 )
3254+ return( ret );
3255+ #endif
3256+#endif
3257+ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
3258+ }
3259+
3260+ /*
3261+ * grp may already be initialized; if so, make sure IDs match
3262+ */
3263+ if( ecp_kp_grp->id != MBEDTLS_ECP_DP_NONE && ecp_kp_grp->id != grp_id )
3264+ return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
3265+
3266+ if( ( ret = mbedtls_ecp_group_load( ecp_kp_grp, grp_id ) ) != 0 )
3267+ return( ret );
3268+
3269+
3270+ /* (validate assumption that EC point is in COMPRESSED format) */
3271+ len = CRYPTO_EC_plen(ecp_kp_grp);
3272+ if( mbedtls_ecp_get_type(ecp_kp_grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS
3273+ || (end - p) != 1+len
3274+ || (*p != 0x02 && *p != 0x03) )
3275+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
3276+
3277+ /* Instead of calling mbedtls/library/pkparse.c:pk_get_ecpubkey() to call
3278+ * mbedtls_ecp_point_read_binary(), manually parse point into ecp_kp_Q */
3279+ mbedtls_mpi *X = &ecp_kp_Q->MBEDTLS_PRIVATE(X);
3280+ mbedtls_mpi *Y = &ecp_kp_Q->MBEDTLS_PRIVATE(Y);
3281+ mbedtls_mpi *Z = &ecp_kp_Q->MBEDTLS_PRIVATE(Z);
3282+ ret = mbedtls_mpi_lset(Z, 1);
3283+ if (ret != 0)
3284+ return( ret );
3285+ ret = mbedtls_mpi_read_binary(X, p+1, len);
3286+ if (ret != 0)
3287+ return( ret );
3288+ /* derive Y
3289+ * (similar derivation of Y in crypto_mbedtls.c:crypto_ecdh_set_peerkey())*/
3290+ ret = mbedtls_mpi_copy(Y, X) /*(Y is used as input and output obj below)*/
3291+ || crypto_mbedtls_short_weierstrass_derive_y(ecp_kp_grp, Y, (*p & 1));
3292+ if (ret != 0)
3293+ return( ret );
3294+
3295+ return mbedtls_ecp_check_pubkey( ecp_kp_grp, ecp_kp_Q );
3296+}
3297+
3298+struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
3299+{
3300+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
3301+ if (ctx == NULL)
3302+ return NULL;
3303+ mbedtls_pk_init(ctx);
3304+ /*int rc = mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx);*/
3305+ int rc = mbedtls_pk_parse_public_key(ctx, der, der_len);
3306+ if (rc == 0)
3307+ return (struct crypto_ec_key *)ctx;
3308+ else if (rc == MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) {
3309+ /* mbedtls mbedtls_ecp_point_read_binary()
3310+ * does not handle point in COMPRESSED format; parse internally */
3311+ rc = crypto_mbedtls_pk_parse_subpubkey_compressed(ctx,der,der_len);
3312+ if (rc == 0)
3313+ return (struct crypto_ec_key *)ctx;
3314+ }
3315+
3316+ mbedtls_pk_free(ctx);
3317+ os_free(ctx);
3318+ return NULL;
3319+}
3320+
3321+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
3322+
3323+static struct crypto_ec_key *
3324+crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id,
3325+ const mbedtls_ecp_point *pub,
3326+ const u8 *buf, size_t len)
3327+{
3328+ const mbedtls_pk_info_t *pk_info =
3329+ mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
3330+ if (pk_info == NULL)
3331+ return NULL;
3332+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
3333+ if (ctx == NULL)
3334+ return NULL;
3335+ mbedtls_pk_init(ctx);
3336+ if (mbedtls_pk_setup(ctx, pk_info) == 0) {
3337+ /* (Is private key generation necessary for callers?)
3338+ * alt: gen key then overwrite Q
3339+ * mbedtls_ecp_gen_key(grp_id, ecp_kp,
3340+ * mbedtls_ctr_drbg_random,
3341+ * crypto_mbedtls_ctr_drbg()) == 0
3342+ */
3343+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx);
3344+ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
3345+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
3346+ mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d);
3347+ if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0
3348+ && (pub
3349+ ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0
3350+ : mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q,
3351+ buf, len) == 0)
3352+ && mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d,
3353+ mbedtls_ctr_drbg_random,
3354+ crypto_mbedtls_ctr_drbg()) == 0){
3355+ return (struct crypto_ec_key *)ctx;
3356+ }
3357+ }
3358+
3359+ mbedtls_pk_free(ctx);
3360+ os_free(ctx);
3361+ return NULL;
3362+}
3363+
3364+struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
3365+ const u8 *y, size_t len)
3366+{
3367+ mbedtls_ecp_group_id grp_id =
3368+ crypto_mbedtls_ecp_group_id_from_ike_id(group);
3369+ if (grp_id == MBEDTLS_ECP_DP_NONE)
3370+ return NULL;
3371+ if (len > MBEDTLS_MPI_MAX_SIZE)
3372+ return NULL;
3373+ u8 buf[1+MBEDTLS_MPI_MAX_SIZE*2];
3374+ buf[0] = 0x04; /* assume x,y for Short Weierstrass */
3375+ os_memcpy(buf+1, x, len);
3376+ os_memcpy(buf+1+len, y, len);
3377+
3378+ return crypto_ec_key_set_pub_point_for_group(grp_id,NULL,buf,1+len*2);
3379+}
3380+
3381+struct crypto_ec_key *
3382+crypto_ec_key_set_pub_point(struct crypto_ec *e,
3383+ const struct crypto_ec_point *pub)
3384+{
3385+ mbedtls_ecp_group_id grp_id = ((mbedtls_ecp_group *)e)->id;
3386+ mbedtls_ecp_point *p = (mbedtls_ecp_point *)pub;
3387+ return crypto_ec_key_set_pub_point_for_group(grp_id, p, NULL, 0);
3388+}
3389+
3390+
3391+struct crypto_ec_key * crypto_ec_key_gen(int group)
3392+{
3393+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
3394+ if (ctx == NULL)
3395+ return NULL;
3396+ mbedtls_pk_init(ctx);
3397+ if (crypto_mbedtls_keypair_gen(group, ctx) == 0)
3398+ return (struct crypto_ec_key *)ctx;
3399+ mbedtls_pk_free(ctx);
3400+ os_free(ctx);
3401+ return NULL;
3402+}
3403+
3404+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
3405+
3406+void crypto_ec_key_deinit(struct crypto_ec_key *key)
3407+{
3408+ mbedtls_pk_free((mbedtls_pk_context *)key);
3409+ os_free(key);
3410+}
3411+
3412+struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
3413+{
3414+ /* (similar to crypto_ec_key_get_pubkey_point(),
3415+ * but compressed point format and ASN.1 DER wrapping)*/
3416+#ifndef MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/
3417+#define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES )
3418+#endif
3419+ unsigned char buf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES];
3420+ int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key,
3421+ buf, sizeof(buf));
3422+ if (len < 0)
3423+ return NULL;
3424+ /* Note: data is written at the end of the buffer! Use the
3425+ * return value to determine where you should start
3426+ * using the buffer */
3427+ unsigned char *p = buf+sizeof(buf)-len;
3428+
3429+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
3430+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
3431+ if (ecp_kp == NULL)
3432+ return NULL;
3433+ mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
3434+ /* Note: sae_pk.c expects pubkey point in compressed format,
3435+ * but mbedtls_pk_write_pubkey_der() writes uncompressed format.
3436+ * Manually translate format and update lengths in DER format */
3437+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) {
3438+ unsigned char *end = buf+sizeof(buf);
3439+ size_t n;
3440+ /* SubjectPublicKeyInfo SEQUENCE */
3441+ mbedtls_asn1_get_tag(&p, end, &n,
3442+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3443+ /* algorithm AlgorithmIdentifier */
3444+ unsigned char *a = p;
3445+ size_t alen;
3446+ mbedtls_asn1_get_tag(&p, end, &alen,
3447+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3448+ p += alen;
3449+ alen = (size_t)(p - a);
3450+ /* subjectPublicKey BIT STRING */
3451+ mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_BIT_STRING);
3452+ /* rewrite into compressed point format and rebuild ASN.1 */
3453+ p[1] = (buf[sizeof(buf)-1] & 1) ? 0x03 : 0x02;
3454+ n = 1 + 1 + (n-2)/2;
3455+ len = mbedtls_asn1_write_len(&p, buf, n) + (int)n;
3456+ len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_BIT_STRING);
3457+ os_memmove(p-alen, a, alen);
3458+ len += alen;
3459+ p -= alen;
3460+ len += mbedtls_asn1_write_len(&p, buf, (size_t)len);
3461+ len += mbedtls_asn1_write_tag(&p, buf,
3462+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3463+ }
3464+ #endif
3465+ return wpabuf_alloc_copy(p, (size_t)len);
3466+}
3467+
3468+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
3469+
3470+struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
3471+ bool include_pub)
3472+{
3473+#ifndef MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/
3474+#define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES )
3475+#endif
3476+ unsigned char priv[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES];
3477+ int privlen = mbedtls_pk_write_key_der((mbedtls_pk_context *)key,
3478+ priv, sizeof(priv));
3479+ if (privlen < 0)
3480+ return NULL;
3481+
3482+ struct wpabuf *wbuf;
3483+
3484+ /* Note: data is written at the end of the buffer! Use the
3485+ * return value to determine where you should start
3486+ * using the buffer */
3487+ /* mbedtls_pk_write_key_der() includes publicKey in DER */
3488+ if (include_pub)
3489+ wbuf = wpabuf_alloc_copy(priv+sizeof(priv)-privlen, privlen);
3490+ else {
3491+ /* calculate publicKey offset and skip from end of buffer */
3492+ unsigned char *p = priv+sizeof(priv)-privlen;
3493+ unsigned char *end = priv+sizeof(priv);
3494+ size_t len;
3495+ /* ECPrivateKey SEQUENCE */
3496+ mbedtls_asn1_get_tag(&p, end, &len,
3497+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3498+ /* version INTEGER */
3499+ unsigned char *v = p;
3500+ mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
3501+ p += len;
3502+ /* privateKey OCTET STRING */
3503+ mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
3504+ p += len;
3505+ /* parameters ECParameters */
3506+ mbedtls_asn1_get_tag(&p, end, &len,
3507+ MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED);
3508+ p += len;
3509+
3510+ /* write new SEQUENCE header (we know that it fits in priv[]) */
3511+ len = (size_t)(p - v);
3512+ p = v;
3513+ len += mbedtls_asn1_write_len(&p, priv, len);
3514+ len += mbedtls_asn1_write_tag(&p, priv,
3515+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3516+ wbuf = wpabuf_alloc_copy(p, len);
3517+ }
3518+
3519+ forced_memzero(priv, sizeof(priv));
3520+ return wbuf;
3521+}
3522+
3523+struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
3524+ int prefix)
3525+{
3526+ /*(similarities to crypto_ecdh_get_pubkey(), but different struct)*/
3527+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
3528+ if (ecp_kp == NULL)
3529+ return NULL;
3530+ mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
3531+ size_t len = CRYPTO_EC_plen(grp);
3532+ #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
3533+ /* len */
3534+ #endif
3535+ #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
3536+ if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS)
3537+ len = len*2+1;
3538+ #endif
3539+ struct wpabuf *buf = wpabuf_alloc(len);
3540+ if (buf == NULL)
3541+ return NULL;
3542+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
3543+ if (mbedtls_ecp_point_write_binary(grp, ecp_kp_Q,
3544+ MBEDTLS_ECP_PF_UNCOMPRESSED, &len,
3545+ wpabuf_mhead_u8(buf), len) == 0) {
3546+ if (!prefix) /* Remove 0x04 prefix if requested */
3547+ os_memmove(wpabuf_mhead(buf),wpabuf_mhead(buf)+1,--len);
3548+ wpabuf_put(buf, len);
3549+ return buf;
3550+ }
3551+
3552+ wpabuf_free(buf);
3553+ return NULL;
3554+}
3555+
3556+struct crypto_ec_point *
3557+crypto_ec_key_get_public_key(struct crypto_ec_key *key)
3558+{
3559+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
3560+ if (ecp_kp == NULL)
3561+ return NULL;
3562+ mbedtls_ecp_point *p = os_malloc(sizeof(*p));
3563+ if (p != NULL) {
3564+ /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/
3565+ mbedtls_ecp_point_init(p);
3566+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
3567+ if (mbedtls_ecp_copy(p, ecp_kp_Q)) {
3568+ mbedtls_ecp_point_free(p);
3569+ os_free(p);
3570+ p = NULL;
3571+ }
3572+ }
3573+ return (struct crypto_ec_point *)p;
3574+}
3575+
3576+struct crypto_bignum *
3577+crypto_ec_key_get_private_key(struct crypto_ec_key *key)
3578+{
3579+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
3580+ if (ecp_kp == NULL)
3581+ return NULL;
3582+ mbedtls_mpi *bn = os_malloc(sizeof(*bn));
3583+ if (bn) {
3584+ /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/
3585+ mbedtls_mpi_init(bn);
3586+ mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d);
3587+ if (mbedtls_mpi_copy(bn, ecp_kp_d)) {
3588+ mbedtls_mpi_free(bn);
3589+ os_free(bn);
3590+ bn = NULL;
3591+ }
3592+ }
3593+ return (struct crypto_bignum *)bn;
3594+}
3595+
3596+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
3597+
3598+static mbedtls_md_type_t crypto_ec_key_sign_md(size_t len)
3599+{
3600+ /* get mbedtls_md_type_t from length of hash data to be signed */
3601+ switch (len) {
3602+ case 64: return MBEDTLS_MD_SHA512;
3603+ case 48: return MBEDTLS_MD_SHA384;
3604+ case 32: return MBEDTLS_MD_SHA256;
3605+ case 20: return MBEDTLS_MD_SHA1;
3606+ case 16: return MBEDTLS_MD_MD5;
3607+ default: return MBEDTLS_MD_NONE;
3608+ }
3609+}
3610+
3611+struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
3612+ size_t len)
3613+{
3614+ #ifndef MBEDTLS_PK_SIGNATURE_MAX_SIZE /*(defined since mbedtls 2.20.0)*/
3615+ #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
3616+ #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
3617+ #else
3618+ #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
3619+ #endif
3620+ #endif
3621+ size_t sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE;
3622+ struct wpabuf *buf = wpabuf_alloc(sig_len);
3623+ if (buf == NULL)
3624+ return NULL;
3625+ if (mbedtls_pk_sign((mbedtls_pk_context *)key,
3626+ crypto_ec_key_sign_md(len), data, len,
3627+ wpabuf_mhead_u8(buf),
3628+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
3629+ sig_len,
3630+ #endif
3631+ &sig_len,
3632+ mbedtls_ctr_drbg_random,
3633+ crypto_mbedtls_ctr_drbg()) == 0) {
3634+ wpabuf_put(buf, sig_len);
3635+ return buf;
3636+ }
3637+
3638+ wpabuf_free(buf);
3639+ return NULL;
3640+}
3641+
3642+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
3643+struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
3644+ const u8 *data, size_t len)
3645+{
3646+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
3647+ if (ecp_kp == NULL)
3648+ return NULL;
3649+
3650+ size_t sig_len = MBEDTLS_ECDSA_MAX_LEN;
3651+ u8 buf[MBEDTLS_ECDSA_MAX_LEN];
3652+ if (mbedtls_ecdsa_write_signature(ecp_kp, crypto_ec_key_sign_md(len),
3653+ data, len, buf,
3654+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
3655+ sig_len,
3656+ #endif
3657+ &sig_len,
3658+ mbedtls_ctr_drbg_random,
3659+ crypto_mbedtls_ctr_drbg())) {
3660+ return NULL;
3661+ }
3662+
3663+ /*(mbedtls_ecdsa_write_signature() writes signature in ASN.1)*/
3664+ /* parse ASN.1 to get r and s and lengths */
3665+ u8 *p = buf, *r, *s;
3666+ u8 *end = p + sig_len;
3667+ size_t rlen, slen;
3668+ mbedtls_asn1_get_tag(&p, end, &rlen,
3669+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3670+ mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_INTEGER);
3671+ r = p;
3672+ p += rlen;
3673+ mbedtls_asn1_get_tag(&p, end, &slen, MBEDTLS_ASN1_INTEGER);
3674+ s = p;
3675+
3676+ /* write raw r and s into out
3677+ * (including removal of leading 0 if added for ASN.1 integer)
3678+ * note: DPP caller expects raw r, s each padded to prime len */
3679+ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
3680+ size_t plen = CRYPTO_EC_plen(ecp_kp_grp);
3681+ if (rlen > plen) {
3682+ r += (rlen - plen);
3683+ rlen = plen;
3684+ }
3685+ if (slen > plen) {
3686+ s += (slen - plen);
3687+ slen = plen;
3688+ }
3689+ struct wpabuf *out = wpabuf_alloc(plen*2);
3690+ if (out) {
3691+ wpabuf_put(out, plen*2);
3692+ p = wpabuf_mhead_u8(out);
3693+ os_memset(p, 0, plen*2);
3694+ os_memcpy(p+plen*1-rlen, r, rlen);
3695+ os_memcpy(p+plen*2-slen, s, slen);
3696+ }
3697+ return out;
3698+}
3699+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
3700+
3701+int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
3702+ size_t len, const u8 *sig, size_t sig_len)
3703+{
3704+ switch (mbedtls_pk_verify((mbedtls_pk_context *)key,
3705+ crypto_ec_key_sign_md(len), data, len,
3706+ sig, sig_len)) {
3707+ case 0:
3708+ /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */
3709+ return 1;
3710+ case MBEDTLS_ERR_ECP_VERIFY_FAILED:
3711+ return 0;
3712+ default:
3713+ return -1;
3714+ }
3715+}
3716+
3717+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
3718+int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
3719+ const u8 *data, size_t len,
3720+ const u8 *r, size_t r_len,
3721+ const u8 *s, size_t s_len)
3722+{
3723+ /* reimplement mbedtls_ecdsa_read_signature() without encoding r and s
3724+ * into ASN.1 just for mbedtls_ecdsa_read_signature() to decode ASN.1 */
3725+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
3726+ if (ecp_kp == NULL)
3727+ return -1;
3728+ mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
3729+ mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
3730+
3731+ mbedtls_mpi mpi_r;
3732+ mbedtls_mpi mpi_s;
3733+ mbedtls_mpi_init(&mpi_r);
3734+ mbedtls_mpi_init(&mpi_s);
3735+ int ret = mbedtls_mpi_read_binary(&mpi_r, r, r_len)
3736+ || mbedtls_mpi_read_binary(&mpi_s, s, s_len) ? -1 : 0;
3737+ if (ret == 0) {
3738+ ret = mbedtls_ecdsa_verify(ecp_kp_grp, data, len,
3739+ ecp_kp_Q, &mpi_r, &mpi_s);
3740+ ret = ret ? ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA ? 0 : -1 : 1;
3741+ }
3742+ mbedtls_mpi_free(&mpi_r);
3743+ mbedtls_mpi_free(&mpi_s);
3744+ return ret;
3745+}
3746+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
3747+
3748+int crypto_ec_key_group(struct crypto_ec_key *key)
3749+{
3750+ mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
3751+ if (ecp_kp == NULL)
3752+ return -1;
3753+ mbedtls_ecp_group *ecp_group = &ecp_kp->MBEDTLS_PRIVATE(grp);
3754+ return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id);
3755+}
3756+
3757+#ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
3758+
3759+int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
3760+{
3761+#if 0 /*(DPP is passing two public keys; unable to use pk_check_pair())*/
3762+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
3763+ return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1,
3764+ (const mbedtls_pk_context *)key2) ? -1 : 0;
3765+ #else
3766+ return mbedtls_pk_check_pair((const mbedtls_pk_context *)key1,
3767+ (const mbedtls_pk_context *)key2,
3768+ mbedtls_ctr_drbg_random,
3769+ crypto_mbedtls_ctr_drbg()) ? -1 : 0;
3770+ #endif
3771+#else
3772+ mbedtls_ecp_keypair *ecp_kp1=mbedtls_pk_ec(*(mbedtls_pk_context *)key1);
3773+ mbedtls_ecp_keypair *ecp_kp2=mbedtls_pk_ec(*(mbedtls_pk_context *)key2);
3774+ if (ecp_kp1 == NULL || ecp_kp2 == NULL)
3775+ return -1;
3776+ mbedtls_ecp_group *ecp_kp1_grp = &ecp_kp1->MBEDTLS_PRIVATE(grp);
3777+ mbedtls_ecp_group *ecp_kp2_grp = &ecp_kp2->MBEDTLS_PRIVATE(grp);
3778+ mbedtls_ecp_point *ecp_kp1_Q = &ecp_kp1->MBEDTLS_PRIVATE(Q);
3779+ mbedtls_ecp_point *ecp_kp2_Q = &ecp_kp2->MBEDTLS_PRIVATE(Q);
3780+ return ecp_kp1_grp->id != ecp_kp2_grp->id
3781+ || mbedtls_ecp_point_cmp(ecp_kp1_Q, ecp_kp2_Q) ? -1 : 0;
3782+#endif
3783+}
3784+
3785+void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
3786+ const char *title)
3787+{
3788+ /* TBD: what info is desirable here and in what human readable format?*/
3789+ /*(crypto_openssl.c prints a human-readably public key and attributes)*/
3790+ #if 0
3791+ struct mbedtls_pk_debug_item debug_item;
3792+ if (mbedtls_pk_debug((const mbedtls_pk_context *)key, &debug_item))
3793+ return;
3794+ /* ... */
3795+ #endif
3796+ wpa_printf(MSG_DEBUG, "%s: %s not implemented", title, __func__);
3797+}
3798+
3799+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
3800+
3801+#endif /* CRYPTO_MBEDTLS_CRYPTO_EC */
3802+
3803+
3804+#ifdef CRYPTO_MBEDTLS_CRYPTO_CSR
3805+
3806+#include <mbedtls/x509_csr.h>
3807+#include <mbedtls/oid.h>
3808+
3809+struct crypto_csr * crypto_csr_init(void)
3810+{
3811+ mbedtls_x509write_csr *csr = os_malloc(sizeof(*csr));
3812+ if (csr != NULL)
3813+ mbedtls_x509write_csr_init(csr);
3814+ return (struct crypto_csr *)csr;
3815+}
3816+
3817+struct crypto_csr * crypto_csr_verify(const struct wpabuf *req)
3818+{
3819+ /* future: look for alternatives to MBEDTLS_PRIVATE() access */
3820+
3821+ /* sole caller src/common/dpp_crypto.c:dpp_validate_csr()
3822+ * uses (mbedtls_x509_csr *) to obtain CSR_ATTR_CHALLENGE_PASSWORD
3823+ * so allocate different object (mbedtls_x509_csr *) and special-case
3824+ * object when used in crypto_csr_get_attribute() and when free()d in
3825+ * crypto_csr_deinit(). */
3826+
3827+ mbedtls_x509_csr *csr = os_malloc(sizeof(*csr));
3828+ if (csr == NULL)
3829+ return NULL;
3830+ mbedtls_x509_csr_init(csr);
3831+ const mbedtls_md_info_t *md_info;
3832+ unsigned char digest[MBEDTLS_MD_MAX_SIZE];
3833+ if (mbedtls_x509_csr_parse_der(csr,wpabuf_head(req),wpabuf_len(req))==0
3834+ && (md_info=mbedtls_md_info_from_type(csr->MBEDTLS_PRIVATE(sig_md)))
3835+ != NULL
3836+ && mbedtls_md(md_info, csr->cri.p, csr->cri.len, digest) == 0) {
3837+ switch (mbedtls_pk_verify(&csr->pk,csr->MBEDTLS_PRIVATE(sig_md),
3838+ digest, mbedtls_md_get_size(md_info),
3839+ csr->MBEDTLS_PRIVATE(sig).p,
3840+ csr->MBEDTLS_PRIVATE(sig).len)) {
3841+ case 0:
3842+ /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*//* XXX: allow? */
3843+ return (struct crypto_csr *)((uintptr_t)csr | 1uL);
3844+ default:
3845+ break;
3846+ }
3847+ }
3848+
3849+ mbedtls_x509_csr_free(csr);
3850+ os_free(csr);
3851+ return NULL;
3852+}
3853+
3854+void crypto_csr_deinit(struct crypto_csr *csr)
3855+{
3856+ if ((uintptr_t)csr & 1uL) {
3857+ csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL);
3858+ mbedtls_x509_csr_free((mbedtls_x509_csr *)csr);
3859+ }
3860+ else
3861+ mbedtls_x509write_csr_free((mbedtls_x509write_csr *)csr);
3862+ os_free(csr);
3863+}
3864+
3865+int crypto_csr_set_ec_public_key(struct crypto_csr *csr,
3866+ struct crypto_ec_key *key)
3867+{
3868+ mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *)csr,
3869+ (mbedtls_pk_context *)key);
3870+ return 0;
3871+}
3872+
3873+int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
3874+ const char *name)
3875+{
3876+ /* specialized for src/common/dpp_crypto.c */
3877+
3878+ /* sole caller src/common/dpp_crypto.c:dpp_build_csr()
3879+ * calls this function only once, using type == CSR_NAME_CN
3880+ * (If called more than once, this code would need to append
3881+ * components to the subject name, which we could do by
3882+ * appending to (mbedtls_x509write_csr *) private member
3883+ * mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject)) */
3884+
3885+ const char *label;
3886+ switch (type) {
3887+ case CSR_NAME_CN: label = "CN="; break;
3888+ case CSR_NAME_SN: label = "SN="; break;
3889+ case CSR_NAME_C: label = "C="; break;
3890+ case CSR_NAME_O: label = "O="; break;
3891+ case CSR_NAME_OU: label = "OU="; break;
3892+ default: return -1;
3893+ }
3894+
3895+ size_t len = strlen(name);
3896+ struct wpabuf *buf = wpabuf_alloc(3+len+1);
3897+ if (buf == NULL)
3898+ return -1;
3899+ wpabuf_put_data(buf, label, strlen(label));
3900+ wpabuf_put_data(buf, name, len+1); /*(include trailing '\0')*/
3901+ /* Note: 'name' provided is set as given and should be backslash-escaped
3902+ * by caller when necessary, e.g. literal ',' which are not separating
3903+ * components should be backslash-escaped */
3904+
3905+ int ret =
3906+ mbedtls_x509write_csr_set_subject_name((mbedtls_x509write_csr *)csr,
3907+ wpabuf_head(buf)) ? -1 : 0;
3908+ wpabuf_free(buf);
3909+ return ret;
3910+}
3911+
3912+/* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */
3913+static const char OBJ_pkcs9_challengePassword[] = MBEDTLS_OID_PKCS9 "\x07";
3914+
3915+int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
3916+ int attr_type, const u8 *value, size_t len)
3917+{
3918+ /* specialized for src/common/dpp_crypto.c */
3919+ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes
3920+ * attr == CSR_ATTR_CHALLENGE_PASSWORD
3921+ * attr_type == ASN1_TAG_UTF8STRING */
3922+
3923+ const char *oid;
3924+ size_t oid_len;
3925+ switch (attr) {
3926+ case CSR_ATTR_CHALLENGE_PASSWORD:
3927+ oid = OBJ_pkcs9_challengePassword;
3928+ oid_len = sizeof(OBJ_pkcs9_challengePassword)-1;
3929+ break;
3930+ default:
3931+ return -1;
3932+ }
3933+
3934+ #if 0 /*(incorrect; sets an extension, not an attribute)*/
3935+ return mbedtls_x509write_csr_set_extension((mbedtls_x509write_csr *)csr,
3936+ oid, oid_len,
3937+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
3938+ 0, /*(critical flag)*/
3939+ #endif
3940+ value, len) ? -1 : 0;
3941+ #else
3942+ (void)oid;
3943+ (void)oid_len;
3944+ #endif
3945+
3946+ /* mbedtls does not currently provide way to set an attribute in a CSR:
3947+ * https://github.com/Mbed-TLS/mbedtls/issues/4886 */
3948+ wpa_printf(MSG_ERROR,
3949+ "mbedtls does not currently support setting challengePassword "
3950+ "attribute in CSR");
3951+ return -1;
3952+}
3953+
3954+const u8 * mbedtls_x509_csr_attr_oid_value(mbedtls_x509_csr *csr,
3955+ const char *oid, size_t oid_len,
3956+ size_t *vlen, int *vtype)
3957+{
3958+ /* Note: mbedtls_x509_csr_parse_der() has parsed and validated CSR,
3959+ * so validation checks are not repeated here
3960+ *
3961+ * It would be nicer if (mbedtls_x509_csr *) had an mbedtls_x509_buf of
3962+ * Attributes (or at least a pointer) since mbedtls_x509_csr_parse_der()
3963+ * already parsed the rest of CertificationRequestInfo, some of which is
3964+ * repeated here to step to Attributes. Since csr->subject_raw.p points
3965+ * into csr->cri.p, which points into csr->raw.p, step over version and
3966+ * subject of CertificationRequestInfo (SEQUENCE) */
3967+ unsigned char *p = csr->subject_raw.p + csr->subject_raw.len;
3968+ unsigned char *end = csr->cri.p + csr->cri.len, *ext;
3969+ size_t len;
3970+
3971+ /* step over SubjectPublicKeyInfo */
3972+ mbedtls_asn1_get_tag(&p, end, &len,
3973+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3974+ p += len;
3975+
3976+ /* Attributes
3977+ * { ATTRIBUTE:IOSet } ::= SET OF { SEQUENCE { OID, value } }
3978+ */
3979+ if (mbedtls_asn1_get_tag(&p, end, &len,
3980+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
3981+ return NULL;
3982+ }
3983+ while (p < end) {
3984+ if (mbedtls_asn1_get_tag(&p, end, &len,
3985+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
3986+ return NULL;
3987+ }
3988+ ext = p;
3989+ p += len;
3990+
3991+ if (mbedtls_asn1_get_tag(&ext,end,&len,MBEDTLS_ASN1_OID) != 0)
3992+ return NULL;
3993+ if (oid_len != len || 0 != memcmp(ext, oid, oid_len))
3994+ continue;
3995+
3996+ /* found oid; return value */
3997+ *vtype = *ext++; /* tag */
3998+ return (mbedtls_asn1_get_len(&ext,end,vlen) == 0) ? ext : NULL;
3999+ }
4000+
4001+ return NULL;
4002+}
4003+
4004+const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
4005+ enum crypto_csr_attr attr,
4006+ size_t *len, int *type)
4007+{
4008+ /* specialized for src/common/dpp_crypto.c */
4009+ /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes
4010+ * attr == CSR_ATTR_CHALLENGE_PASSWORD */
4011+
4012+ const char *oid;
4013+ size_t oid_len;
4014+ switch (attr) {
4015+ case CSR_ATTR_CHALLENGE_PASSWORD:
4016+ oid = OBJ_pkcs9_challengePassword;
4017+ oid_len = sizeof(OBJ_pkcs9_challengePassword)-1;
4018+ break;
4019+ default:
4020+ return NULL;
4021+ }
4022+
4023+ /* see crypto_csr_verify(); expecting (mbedtls_x509_csr *) tagged |=1 */
4024+ if (!((uintptr_t)csr & 1uL))
4025+ return NULL;
4026+ csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL);
4027+
4028+ return mbedtls_x509_csr_attr_oid_value((mbedtls_x509_csr *)csr,
4029+ oid, oid_len, len, type);
4030+}
4031+
4032+struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
4033+ struct crypto_ec_key *key,
4034+ enum crypto_hash_alg algo)
4035+{
4036+ mbedtls_md_type_t sig_md;
4037+ switch (algo) {
4038+ #ifdef MBEDTLS_SHA256_C
4039+ case CRYPTO_HASH_ALG_SHA256: sig_md = MBEDTLS_MD_SHA256; break;
4040+ #endif
4041+ #ifdef MBEDTLS_SHA512_C
4042+ case CRYPTO_HASH_ALG_SHA384: sig_md = MBEDTLS_MD_SHA384; break;
4043+ case CRYPTO_HASH_ALG_SHA512: sig_md = MBEDTLS_MD_SHA512; break;
4044+ #endif
4045+ default:
4046+ return NULL;
4047+ }
4048+ mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md);
4049+
4050+ #if 0
4051+ unsigned char key_usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE
4052+ | MBEDTLS_X509_KU_KEY_CERT_SIGN;
4053+ if (mbedtls_x509write_csr_set_key_usage((mbedtls_x509write_csr *)csr,
4054+ key_usage))
4055+ return NULL;
4056+ #endif
4057+
4058+ #if 0
4059+ unsigned char ns_cert_type = MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT
4060+ | MBEDTLS_X509_NS_CERT_TYPE_EMAIL;
4061+ if (mbedtls_x509write_csr_set_ns_cert_type((mbedtls_x509write_csr *)csr,
4062+ ns_cert_type))
4063+ return NULL;
4064+ #endif
4065+
4066+ #if 0
4067+ /* mbedtls does not currently provide way to set an attribute in a CSR:
4068+ * https://github.com/Mbed-TLS/mbedtls/issues/4886
4069+ * XXX: hwsim dpp_enterprise test fails due to this limitation.
4070+ *
4071+ * Current usage of this function is solely by dpp_build_csr(),
4072+ * so as a kludge, might consider custom (struct crypto_csr *)
4073+ * containing (mbedtls_x509write_csr *) and a list of attributes
4074+ * (i.e. challengePassword). Might have to totally reimplement
4075+ * mbedtls_x509write_csr_der(); underlying x509write_csr_der_internal()
4076+ * handles signing the CSR. (This is more work that appending an
4077+ * Attributes section to end of CSR and adjusting ASN.1 length of CSR.)
4078+ */
4079+ #endif
4080+
4081+ unsigned char buf[4096]; /* XXX: large enough? too large? */
4082+ int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr,
4083+ buf, sizeof(buf),
4084+ mbedtls_ctr_drbg_random,
4085+ crypto_mbedtls_ctr_drbg());
4086+ if (len < 0)
4087+ return NULL;
4088+ /* Note: data is written at the end of the buffer! Use the
4089+ * return value to determine where you should start
4090+ * using the buffer */
4091+ return wpabuf_alloc_copy(buf+sizeof(buf)-len, (size_t)len);
4092+}
4093+
4094+#endif /* CRYPTO_MBEDTLS_CRYPTO_CSR */
4095+
4096+
4097+#ifdef CRYPTO_MBEDTLS_CRYPTO_PKCS7
4098+
4099+#if 0
4100+#include <mbedtls/pkcs7.h> /* PKCS7 is not currently supported in mbedtls */
4101+#include <mbedtls/pem.h>
4102+#endif
4103+
4104+struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
4105+{
4106+ /* PKCS7 is not currently supported in mbedtls */
4107+ return NULL;
4108+
4109+#if 0
4110+ /* https://github.com/naynajain/mbedtls-1 branch: development-pkcs7
4111+ * (??? potential future contribution to mbedtls ???) */
4112+
4113+ /* Note: PKCS7 signature *is not* verified by this function.
4114+ * The function interface does not provide for passing a certificate */
4115+
4116+ mbedtls_pkcs7 mpkcs7;
4117+ mbedtls_pkcs7_init(&mpkcs7);
4118+ int pkcs7_type = mbedtls_pkcs7_parse_der(wpabuf_head(pkcs7),
4119+ wpabuf_len(pkcs7),
4120+ &mpkcs7);
4121+ wpabuf *buf = NULL;
4122+ do {
4123+ if (pkcs7_type < 0)
4124+ break;
4125+
4126+ /* src/common/dpp.c:dpp_parse_cred_dot1x() interested in certs
4127+ * for wpa_supplicant/dpp_supplicant.c:wpas_dpp_add_network()
4128+ * (? are adding certificate headers and footers desired ?) */
4129+
4130+ /* development-pkcs7 branch does not currently provide
4131+ * additional interfaces to retrieve the parsed data */
4132+
4133+ mbedtls_x509_crt *certs =
4134+ &mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(certs);
4135+ int ncerts =
4136+ mpkcs7.MBEDTLS_PRIVATE(signed_data).MBEDTLS_PRIVATE(no_of_certs);
4137+
4138+ /* allocate buffer for PEM (base64-encoded DER)
4139+ * plus header, footer, newlines, and some extra */
4140+ buf = wpabuf_alloc((wpabuf_len(pkcs7)+2)/3*4 + ncerts*64);
4141+ if (buf == NULL)
4142+ break;
4143+
4144+ #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
4145+ #define PEM_END_CRT "-----END CERTIFICATE-----\n"
4146+ size_t olen;
4147+ for (int i = 0; i < ncerts; ++i) {
4148+ int ret = mbedtls_pem_write_buffer(
4149+ PEM_BEGIN_CRT, PEM_END_CRT,
4150+ certs[i].raw.p, certs[i].raw.len,
4151+ wpabuf_mhead(buf, 0), wpabuf_tailroom(buf),
4152+ &olen));
4153+ if (ret == 0)
4154+ wpabuf_put(buf, olen);
4155+ } else {
4156+ if (ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL)
4157+ ret = wpabuf_resize(
4158+ &buf,olen-wpabuf_tailroom(buf));
4159+ if (ret == 0) {
4160+ --i;/*(adjust loop iterator for retry)*/
4161+ continue;
4162+ }
4163+ wpabuf_free(buf);
4164+ buf = NULL;
4165+ break;
4166+ }
4167+ }
4168+ } while (0);
4169+
4170+ mbedtls_pkcs7_free(&mpkcs7);
4171+ return buf;
4172+#endif
4173+}
4174+
4175+#endif /* CRYPTO_MBEDTLS_CRYPTO_PKCS7 */
4176+
4177+
4178+#ifdef MBEDTLS_ARC4_C
4179+#include <mbedtls/arc4.h>
4180+int rc4_skip(const u8 *key, size_t keylen, size_t skip,
4181+ u8 *data, size_t data_len)
4182+{
4183+ mbedtls_arc4_context ctx;
4184+ mbedtls_arc4_init(&ctx);
4185+ mbedtls_arc4_setup(&ctx, key, keylen);
4186+
4187+ if (skip) {
4188+ /*(prefer [16] on ancient hardware with smaller cache lines)*/
4189+ unsigned char skip_buf[64]; /*('skip' is generally small)*/
4190+ /*os_memset(skip_buf, 0, sizeof(skip_buf));*/ /*(necessary?)*/
4191+ size_t len;
4192+ do {
4193+ len = skip > sizeof(skip_buf) ? sizeof(skip_buf) : skip;
4194+ mbedtls_arc4_crypt(&ctx, len, skip_buf, skip_buf);
4195+ } while ((skip -= len));
4196+ }
4197+
4198+ int ret = mbedtls_arc4_crypt(&ctx, data_len, data, data);
4199+ mbedtls_arc4_free(&ctx);
4200+ return ret;
4201+}
4202+#endif
4203+
4204+
4205+/* duplicated in tls_mbedtls.c:tls_mbedtls_readfile()*/
4206+__attribute_noinline__
4207+static int crypto_mbedtls_readfile(const char *path, u8 **buf, size_t *n)
4208+{
4209+ #if 0 /* #ifdef MBEDTLS_FS_IO */
4210+ /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/
4211+ if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) {
4212+ wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path);
4213+ return -1;
4214+ }
4215+ #else
4216+ /*(use os_readfile() so that we can use os_free()
4217+ *(if we use mbedtls_pk_load_file() above, macros prevent calling free()
4218+ * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free()
4219+ * on buf aborts in tests if buf not allocated via os_malloc())*/
4220+ *buf = (u8 *)os_readfile(path, n);
4221+ if (!*buf) {
4222+ wpa_printf(MSG_ERROR, "error: os_readfile %s", path);
4223+ return -1;
4224+ }
4225+ u8 *buf0 = os_realloc(*buf, *n+1);
4226+ if (!buf0) {
4227+ bin_clear_free(*buf, *n);
4228+ *buf = NULL;
4229+ return -1;
4230+ }
4231+ buf0[(*n)++] = '\0';
4232+ *buf = buf0;
4233+ #endif
4234+ return 0;
4235+}
4236+
4237+
4238+#ifdef CRYPTO_MBEDTLS_CRYPTO_RSA
4239+#ifdef MBEDTLS_RSA_C
4240+
4241+#include <mbedtls/pk.h>
4242+#include <mbedtls/rsa.h>
4243+
4244+struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key)
4245+{
4246+ /* mbedtls_pk_parse_keyfile() and mbedtls_pk_parse_public_keyfile()
4247+ * require #ifdef MBEDTLS_FS_IO in mbedtls library. Prefer to use
4248+ * crypto_mbedtls_readfile(), which wraps os_readfile() */
4249+ u8 *data;
4250+ size_t len;
4251+ if (crypto_mbedtls_readfile(file, &data, &len) != 0)
4252+ return NULL;
4253+
4254+ mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
4255+ if (ctx == NULL) {
4256+ bin_clear_free(data, len);
4257+ return NULL;
4258+ }
4259+ mbedtls_pk_init(ctx);
4260+
4261+ int rc;
4262+ rc = (private_key
4263+ ? mbedtls_pk_parse_key(ctx, data, len, NULL, 0
4264+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
4265+ ,mbedtls_ctr_drbg_random,
4266+ crypto_mbedtls_ctr_drbg()
4267+ #endif
4268+ )
4269+ : mbedtls_pk_parse_public_key(ctx, data, len)) == 0
4270+ && mbedtls_pk_can_do(ctx, MBEDTLS_PK_RSA);
4271+
4272+ bin_clear_free(data, len);
4273+
4274+ if (rc) {
4275+ /* use MBEDTLS_RSA_PKCS_V21 padding for RSAES-OAEP */
4276+ /* use MBEDTLS_MD_SHA256 for these hostap interfaces */
4277+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
4278+ /*(no return value in mbedtls 2.x)*/
4279+ mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx),
4280+ MBEDTLS_RSA_PKCS_V21,
4281+ MBEDTLS_MD_SHA256);
4282+ #else
4283+ if (mbedtls_rsa_set_padding(mbedtls_pk_rsa(*ctx),
4284+ MBEDTLS_RSA_PKCS_V21,
4285+ MBEDTLS_MD_SHA256) == 0)
4286+ #endif
4287+ return (struct crypto_rsa_key *)ctx;
4288+ }
4289+
4290+ mbedtls_pk_free(ctx);
4291+ os_free(ctx);
4292+ return NULL;
4293+}
4294+
4295+struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key,
4296+ const struct wpabuf *in)
4297+{
4298+ mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key);
4299+ size_t olen = mbedtls_rsa_get_len(pk_rsa);
4300+ struct wpabuf *buf = wpabuf_alloc(olen);
4301+ if (buf == NULL)
4302+ return NULL;
4303+
4304+ /* mbedtls_pk_encrypt() takes a few more hops to get to same func */
4305+ if (mbedtls_rsa_rsaes_oaep_encrypt(pk_rsa,
4306+ mbedtls_ctr_drbg_random,
4307+ crypto_mbedtls_ctr_drbg(),
4308+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
4309+ MBEDTLS_RSA_PRIVATE,
4310+ #endif
4311+ NULL, 0,
4312+ wpabuf_len(in), wpabuf_head(in),
4313+ wpabuf_put(buf, olen)) == 0) {
4314+ return buf;
4315+ }
4316+
4317+ wpabuf_clear_free(buf);
4318+ return NULL;
4319+}
4320+
4321+struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key,
4322+ const struct wpabuf *in)
4323+{
4324+ mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(*(mbedtls_pk_context*)key);
4325+ size_t olen = mbedtls_rsa_get_len(pk_rsa);
4326+ struct wpabuf *buf = wpabuf_alloc(olen);
4327+ if (buf == NULL)
4328+ return NULL;
4329+
4330+ /* mbedtls_pk_decrypt() takes a few more hops to get to same func */
4331+ if (mbedtls_rsa_rsaes_oaep_decrypt(pk_rsa,
4332+ mbedtls_ctr_drbg_random,
4333+ crypto_mbedtls_ctr_drbg(),
4334+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
4335+ MBEDTLS_RSA_PUBLIC,
4336+ #endif
4337+ NULL, 0, &olen, wpabuf_head(in),
4338+ wpabuf_mhead(buf), olen) == 0) {
4339+ wpabuf_put(buf, olen);
4340+ return buf;
4341+ }
4342+
4343+ wpabuf_clear_free(buf);
4344+ return NULL;
4345+}
4346+
4347+void crypto_rsa_key_free(struct crypto_rsa_key *key)
4348+{
4349+ mbedtls_pk_free((mbedtls_pk_context *)key);
4350+ os_free(key);
4351+}
4352+
4353+#endif /* MBEDTLS_RSA_C */
4354+#endif /* CRYPTO_MBEDTLS_CRYPTO_RSA */
4355+
4356+#ifdef CRYPTO_MBEDTLS_CRYPTO_HPKE
4357+
4358+struct wpabuf * hpke_base_seal(enum hpke_kem_id kem_id,
4359+ enum hpke_kdf_id kdf_id,
4360+ enum hpke_aead_id aead_id,
4361+ struct crypto_ec_key *peer_pub,
4362+ const u8 *info, size_t info_len,
4363+ const u8 *aad, size_t aad_len,
4364+ const u8 *pt, size_t pt_len)
4365+{
4366+ /* not yet implemented */
4367+ return NULL;
4368+}
4369+
4370+struct wpabuf * hpke_base_open(enum hpke_kem_id kem_id,
4371+ enum hpke_kdf_id kdf_id,
4372+ enum hpke_aead_id aead_id,
4373+ struct crypto_ec_key *own_priv,
4374+ const u8 *info, size_t info_len,
4375+ const u8 *aad, size_t aad_len,
4376+ const u8 *enc_ct, size_t enc_ct_len)
4377+{
4378+ /* not yet implemented */
4379+ return NULL;
4380+}
4381+
4382+#endif
4383--- /dev/null
4384+++ b/src/crypto/tls_mbedtls.c
4385@@ -0,0 +1,3313 @@
4386+/*
4387+ * SSL/TLS interface functions for mbed TLS
4388+ *
4389+ * SPDX-FileCopyrightText: 2022 Glenn Strauss <gstrauss@gluelogic.com>
4390+ * SPDX-License-Identifier: BSD-3-Clause
4391+ *
4392+ * This software may be distributed under the terms of the BSD license.
4393+ * See README for more details.
4394+ *
4395+ * template: src/crypto/tls_none.c
4396+ * reference: src/crypto/tls_*.c
4397+ *
4398+ * Known Limitations:
4399+ * - no TLSv1.3 (not available in mbedtls 2.x; experimental in mbedtls 3.x)
4400+ * - no OCSP (not yet available in mbedtls)
4401+ * - mbedtls does not support all certificate encodings used by hwsim tests
4402+ * PCKS#5 v1.5
4403+ * PCKS#12
4404+ * DH DSA
4405+ * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c
4406+ * - mbedtls does not currently provide way to set an attribute in a CSR
4407+ * https://github.com/Mbed-TLS/mbedtls/issues/4886
4408+ * so tests/hwsim dpp_enterprise tests fail
4409+ * - DPP2 not supported
4410+ * PKCS#7 parsing is not supported in mbedtls
4411+ * See crypto_mbedtls.c:crypto_pkcs7_get_certificates() comments
4412+ * - DPP3 not supported
4413+ * hpke_base_seal() and hpke_base_seal() not implemented in crypto_mbedtls.c
4414+ *
4415+ * Status:
4416+ * - code written to be compatible with mbedtls 2.x and mbedtls 3.x
4417+ * (currently requires mbedtls >= 2.27.0 for mbedtls_mpi_random())
4418+ * (currently requires mbedtls >= 2.18.0 for mbedtls_ssl_tls_prf())
4419+ * - builds with tests/build/build-wpa_supplicant-mbedtls.config
4420+ * - passes all tests/ crypto module tests (incomplete coverage)
4421+ * ($ cd tests; make clean; make -j 4 run-tests CONFIG_TLS=mbedtls)
4422+ * - passes almost all tests/hwsim tests
4423+ * (hwsim tests skipped for missing features)
4424+ *
4425+ * RFE:
4426+ * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c
4427+ * - client/server session resumption, and/or save client session ticket
4428+ */
4429+
4430+#include "includes.h"
4431+#include "common.h"
4432+
4433+#include <mbedtls/version.h>
4434+#include <mbedtls/ctr_drbg.h>
4435+#include <mbedtls/error.h>
4436+#include <mbedtls/oid.h>
4437+#include <mbedtls/pem.h>
4438+#include <mbedtls/platform.h> /* mbedtls_calloc() mbedtls_free() */
4439+#include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */
4440+#include <mbedtls/ssl.h>
4441+#include <mbedtls/ssl_ticket.h>
4442+#include <mbedtls/x509.h>
4443+#include <mbedtls/x509_crt.h>
4444+
4445+#if MBEDTLS_VERSION_NUMBER >= 0x02040000 /* mbedtls 2.4.0 */
4446+#include <mbedtls/net_sockets.h>
4447+#else
4448+#include <mbedtls/net.h>
4449+#endif
4450+
4451+#ifndef MBEDTLS_PRIVATE
4452+#define MBEDTLS_PRIVATE(x) x
4453+#endif
4454+
4455+#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */
4456+#define mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl) \
4457+ ((ssl)->MBEDTLS_PRIVATE(session) \
4458+ ?(ssl)->MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(ciphersuite) \
4459+ : 0)
4460+#define mbedtls_ssl_ciphersuite_get_name(info) \
4461+ (info)->MBEDTLS_PRIVATE(name)
4462+#endif
4463+
4464+#include "crypto.h" /* sha256_vector() */
4465+#include "tls.h"
4466+
4467+#ifndef SHA256_DIGEST_LENGTH
4468+#define SHA256_DIGEST_LENGTH 32
4469+#endif
4470+
4471+#ifndef MBEDTLS_EXPKEY_FIXED_SECRET_LEN
4472+#define MBEDTLS_EXPKEY_FIXED_SECRET_LEN 48
4473+#endif
4474+
4475+#ifndef MBEDTLS_EXPKEY_RAND_LEN
4476+#define MBEDTLS_EXPKEY_RAND_LEN 32
4477+#endif
4478+
4479+#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
4480+static mbedtls_ssl_export_keys_t tls_connection_export_keys_cb;
4481+#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
4482+static mbedtls_ssl_export_keys_ext_t tls_connection_export_keys_cb;
4483+#else /*(not implemented; return error)*/
4484+#define mbedtls_ssl_tls_prf(a,b,c,d,e,f,g,h) (-1)
4485+typedef mbedtls_tls_prf_types int;
4486+#endif
4487+
4488+
4489+/* hostapd/wpa_supplicant provides forced_memzero(),
4490+ * but prefer mbedtls_platform_zeroize() */
4491+#define forced_memzero(ptr,sz) mbedtls_platform_zeroize(ptr,sz)
4492+
4493+
4494+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) \
4495+ || defined(EAP_TEAP) || defined(EAP_SERVER_TEAP)
4496+#ifdef MBEDTLS_SSL_SESSION_TICKETS
4497+#ifdef MBEDTLS_SSL_TICKET_C
4498+#define TLS_MBEDTLS_SESSION_TICKETS
4499+#if defined(EAP_TEAP) || defined(EAP_SERVER_TEAP)
4500+#define TLS_MBEDTLS_EAP_TEAP
4501+#endif
4502+#if !defined(CONFIG_FIPS) /* EAP-FAST keys cannot be exported in FIPS mode */
4503+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
4504+#define TLS_MBEDTLS_EAP_FAST
4505+#endif
4506+#endif
4507+#endif
4508+#endif
4509+#endif
4510+
4511+
4512+struct tls_conf {
4513+ mbedtls_ssl_config conf;
4514+
4515+ unsigned int verify_peer:1;
4516+ unsigned int verify_depth0_only:1;
4517+ unsigned int check_crl:2; /*(needs :2 bits for 0, 1, 2)*/
4518+ unsigned int check_crl_strict:1; /*(needs :1 bit for 0, 1)*/
4519+ unsigned int ca_cert_probe:1;
4520+ unsigned int has_ca_cert:1;
4521+ unsigned int has_client_cert:1;
4522+ unsigned int has_private_key:1;
4523+ unsigned int suiteb128:1;
4524+ unsigned int suiteb192:1;
4525+ mbedtls_x509_crl *crl;
4526+ mbedtls_x509_crt ca_cert;
4527+ mbedtls_x509_crt client_cert;
4528+ mbedtls_pk_context private_key;
4529+
4530+ uint32_t refcnt;
4531+
4532+ unsigned int flags;
4533+ char *subject_match;
4534+ char *altsubject_match;
4535+ char *suffix_match;
4536+ char *domain_match;
4537+ char *check_cert_subject;
4538+ u8 ca_cert_hash[SHA256_DIGEST_LENGTH];
4539+
4540+ int *ciphersuites; /* list of ciphersuite ids for mbedtls_ssl_config */
4541+#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */
4542+ mbedtls_ecp_group_id *curves;
4543+#else
4544+ uint16_t *curves; /* list of curve ids for mbedtls_ssl_config */
4545+#endif
4546+};
4547+
4548+
4549+struct tls_global {
4550+ struct tls_conf *tls_conf;
4551+ char *ocsp_stapling_response;
4552+ mbedtls_ctr_drbg_context *ctr_drbg; /*(see crypto_mbedtls.c)*/
4553+ #ifdef MBEDTLS_SSL_SESSION_TICKETS
4554+ mbedtls_ssl_ticket_context ticket_ctx;
4555+ #endif
4556+ char *ca_cert_file;
4557+ struct os_reltime crl_reload_previous;
4558+ unsigned int crl_reload_interval;
4559+ uint32_t refcnt;
4560+ struct tls_config init_conf;
4561+};
4562+
4563+static struct tls_global tls_ctx_global;
4564+
4565+
4566+struct tls_connection {
4567+ struct tls_conf *tls_conf;
4568+ struct wpabuf *push_buf;
4569+ struct wpabuf *pull_buf;
4570+ size_t pull_buf_offset;
4571+
4572+ unsigned int established:1;
4573+ unsigned int resumed:1;
4574+ unsigned int verify_peer:1;
4575+ unsigned int is_server:1;
4576+
4577+ mbedtls_ssl_context ssl;
4578+
4579+ mbedtls_tls_prf_types tls_prf_type;
4580+ size_t expkey_keyblock_size;
4581+ size_t expkey_secret_len;
4582+ #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
4583+ unsigned char expkey_secret[MBEDTLS_EXPKEY_FIXED_SECRET_LEN];
4584+ #else
4585+ unsigned char expkey_secret[MBEDTLS_MD_MAX_SIZE];
4586+ #endif
4587+ unsigned char expkey_randbytes[MBEDTLS_EXPKEY_RAND_LEN*2];
4588+
4589+ int read_alerts, write_alerts, failed;
4590+
4591+ #ifdef TLS_MBEDTLS_SESSION_TICKETS
4592+ tls_session_ticket_cb session_ticket_cb;
4593+ void *session_ticket_cb_ctx;
4594+ unsigned char *clienthello_session_ticket;
4595+ size_t clienthello_session_ticket_len;
4596+ #endif
4597+ char *peer_subject; /* peer subject info for authenticated peer */
4598+ struct wpabuf *success_data;
4599+};
4600+
4601+
4602+#ifndef __has_attribute
4603+#define __has_attribute(x) 0
4604+#endif
4605+
4606+#ifndef __GNUC_PREREQ
4607+#define __GNUC_PREREQ(maj,min) 0
4608+#endif
4609+
4610+#ifndef __attribute_cold__
4611+#if __has_attribute(cold) \
4612+ || __GNUC_PREREQ(4,3)
4613+#define __attribute_cold__ __attribute__((__cold__))
4614+#else
4615+#define __attribute_cold__
4616+#endif
4617+#endif
4618+
4619+#ifndef __attribute_noinline__
4620+#if __has_attribute(noinline) \
4621+ || __GNUC_PREREQ(3,1)
4622+#define __attribute_noinline__ __attribute__((__noinline__))
4623+#else
4624+#define __attribute_noinline__
4625+#endif
4626+#endif
4627+
4628+
4629+__attribute_cold__
4630+__attribute_noinline__
4631+static void emsg(int level, const char * const msg)
4632+{
4633+ wpa_printf(level, "MTLS: %s", msg);
4634+}
4635+
4636+
4637+__attribute_cold__
4638+__attribute_noinline__
4639+static void emsgrc(int level, const char * const msg, int rc)
4640+{
4641+ #ifdef MBEDTLS_ERROR_C
4642+ /* error logging convenience function that decodes mbedtls result codes */
4643+ char buf[256];
4644+ mbedtls_strerror(rc, buf, sizeof(buf));
4645+ wpa_printf(level, "MTLS: %s: %s (-0x%04x)", msg, buf, -rc);
4646+ #else
4647+ wpa_printf(level, "MTLS: %s: (-0x%04x)", msg, -rc);
4648+ #endif
4649+}
4650+
4651+
4652+#define elog(rc, msg) emsgrc(MSG_ERROR, (msg), (rc))
4653+#define ilog(rc, msg) emsgrc(MSG_INFO, (msg), (rc))
4654+
4655+
4656+struct tls_conf * tls_conf_init(void *tls_ctx)
4657+{
4658+ struct tls_conf *tls_conf = os_zalloc(sizeof(*tls_conf));
4659+ if (tls_conf == NULL)
4660+ return NULL;
4661+ tls_conf->refcnt = 1;
4662+
4663+ mbedtls_ssl_config_init(&tls_conf->conf);
4664+ mbedtls_ssl_conf_rng(&tls_conf->conf,
4665+ mbedtls_ctr_drbg_random, tls_ctx_global.ctr_drbg);
4666+ mbedtls_x509_crt_init(&tls_conf->ca_cert);
4667+ mbedtls_x509_crt_init(&tls_conf->client_cert);
4668+ mbedtls_pk_init(&tls_conf->private_key);
4669+
4670+ return tls_conf;
4671+}
4672+
4673+
4674+void tls_conf_deinit(struct tls_conf *tls_conf)
4675+{
4676+ if (tls_conf == NULL || --tls_conf->refcnt != 0)
4677+ return;
4678+
4679+ mbedtls_x509_crt_free(&tls_conf->ca_cert);
4680+ mbedtls_x509_crt_free(&tls_conf->client_cert);
4681+ if (tls_conf->crl) {
4682+ mbedtls_x509_crl_free(tls_conf->crl);
4683+ os_free(tls_conf->crl);
4684+ }
4685+ mbedtls_pk_free(&tls_conf->private_key);
4686+ mbedtls_ssl_config_free(&tls_conf->conf);
4687+ os_free(tls_conf->curves);
4688+ os_free(tls_conf->ciphersuites);
4689+ os_free(tls_conf->subject_match);
4690+ os_free(tls_conf->altsubject_match);
4691+ os_free(tls_conf->suffix_match);
4692+ os_free(tls_conf->domain_match);
4693+ os_free(tls_conf->check_cert_subject);
4694+ os_free(tls_conf);
4695+}
4696+
4697+
4698+mbedtls_ctr_drbg_context * crypto_mbedtls_ctr_drbg(void); /*(not in header)*/
4699+
4700+__attribute_cold__
4701+void * tls_init(const struct tls_config *conf)
4702+{
4703+ /* RFE: review struct tls_config *conf (different from tls_conf) */
4704+
4705+ if (++tls_ctx_global.refcnt > 1)
4706+ return &tls_ctx_global;
4707+
4708+ tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg();
4709+ #ifdef MBEDTLS_SSL_SESSION_TICKETS
4710+ mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx);
4711+ mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx,
4712+ mbedtls_ctr_drbg_random,
4713+ tls_ctx_global.ctr_drbg,
4714+ MBEDTLS_CIPHER_AES_256_GCM,
4715+ 43200); /* ticket timeout: 12 hours */
4716+ #endif
4717+ /* copy struct for future use */
4718+ tls_ctx_global.init_conf = *conf;
4719+ if (conf->openssl_ciphers)
4720+ tls_ctx_global.init_conf.openssl_ciphers =
4721+ os_strdup(conf->openssl_ciphers);
4722+
4723+ tls_ctx_global.crl_reload_interval = conf->crl_reload_interval;
4724+ os_get_reltime(&tls_ctx_global.crl_reload_previous);
4725+
4726+ return &tls_ctx_global;
4727+}
4728+
4729+
4730+__attribute_cold__
4731+void tls_deinit(void *tls_ctx)
4732+{
4733+ if (tls_ctx == NULL || --tls_ctx_global.refcnt != 0)
4734+ return;
4735+
4736+ tls_conf_deinit(tls_ctx_global.tls_conf);
4737+ os_free(tls_ctx_global.ca_cert_file);
4738+ os_free(tls_ctx_global.ocsp_stapling_response);
4739+ char *openssl_ciphers; /*(allocated in tls_init())*/
4740+ *(const char **)&openssl_ciphers =
4741+ tls_ctx_global.init_conf.openssl_ciphers;
4742+ os_free(openssl_ciphers);
4743+ #ifdef MBEDTLS_SSL_SESSION_TICKETS
4744+ mbedtls_ssl_ticket_free(&tls_ctx_global.ticket_ctx);
4745+ #endif
4746+ os_memset(&tls_ctx_global, 0, sizeof(tls_ctx_global));
4747+}
4748+
4749+
4750+int tls_get_errors(void *tls_ctx)
4751+{
4752+ return 0;
4753+}
4754+
4755+
4756+static void tls_connection_deinit_expkey(struct tls_connection *conn)
4757+{
4758+ conn->tls_prf_type = 0; /* MBEDTLS_SSL_TLS_PRF_NONE; */
4759+ conn->expkey_keyblock_size = 0;
4760+ conn->expkey_secret_len = 0;
4761+ forced_memzero(conn->expkey_secret, sizeof(conn->expkey_secret));
4762+ forced_memzero(conn->expkey_randbytes, sizeof(conn->expkey_randbytes));
4763+}
4764+
4765+
4766+#ifdef TLS_MBEDTLS_SESSION_TICKETS
4767+void tls_connection_deinit_clienthello_session_ticket(struct tls_connection *conn)
4768+{
4769+ if (conn->clienthello_session_ticket) {
4770+ mbedtls_platform_zeroize(conn->clienthello_session_ticket,
4771+ conn->clienthello_session_ticket_len);
4772+ mbedtls_free(conn->clienthello_session_ticket);
4773+ conn->clienthello_session_ticket = NULL;
4774+ conn->clienthello_session_ticket_len = 0;
4775+ }
4776+}
4777+#endif
4778+
4779+
4780+void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
4781+{
4782+ if (conn == NULL)
4783+ return;
4784+
4785+ #if 0 /*(good intention, but never sent since we destroy self below)*/
4786+ if (conn->established)
4787+ mbedtls_ssl_close_notify(&conn->ssl);
4788+ #endif
4789+
4790+ if (conn->tls_prf_type)
4791+ tls_connection_deinit_expkey(conn);
4792+
4793+ #ifdef TLS_MBEDTLS_SESSION_TICKETS
4794+ if (conn->clienthello_session_ticket)
4795+ tls_connection_deinit_clienthello_session_ticket(conn);
4796+ #endif
4797+
4798+ os_free(conn->peer_subject);
4799+ wpabuf_free(conn->success_data);
4800+ wpabuf_free(conn->push_buf);
4801+ wpabuf_free(conn->pull_buf);
4802+ mbedtls_ssl_free(&conn->ssl);
4803+ tls_conf_deinit(conn->tls_conf);
4804+ os_free(conn);
4805+}
4806+
4807+
4808+static void tls_mbedtls_refresh_crl(void);
4809+static int tls_mbedtls_ssl_setup(struct tls_connection *conn);
4810+
4811+struct tls_connection * tls_connection_init(void *tls_ctx)
4812+{
4813+ struct tls_connection *conn = os_zalloc(sizeof(*conn));
4814+ if (conn == NULL)
4815+ return NULL;
4816+
4817+ mbedtls_ssl_init(&conn->ssl);
4818+
4819+ conn->tls_conf = tls_ctx_global.tls_conf; /*(inherit global conf, if set)*/
4820+ if (conn->tls_conf) {
4821+ ++conn->tls_conf->refcnt;
4822+ /* check for CRL refresh if inheriting from global config */
4823+ tls_mbedtls_refresh_crl();
4824+
4825+ conn->verify_peer = conn->tls_conf->verify_peer;
4826+ if (tls_mbedtls_ssl_setup(conn) != 0) {
4827+ tls_connection_deinit(&tls_ctx_global, conn);
4828+ return NULL;
4829+ }
4830+ }
4831+
4832+ return conn;
4833+}
4834+
4835+
4836+int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
4837+{
4838+ return conn ? conn->established : 0;
4839+}
4840+
4841+
4842+__attribute_noinline__
4843+char * tls_mbedtls_peer_serial_num(const mbedtls_x509_crt *crt, char *serial_num, size_t len)
4844+{
4845+ /* mbedtls_x509_serial_gets() inefficiently formats to hex separated by
4846+ * colons, so generate the hex serial number here. The func
4847+ * wpa_snprintf_hex_uppercase() is similarly inefficient. */
4848+ size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */
4849+ while (i < crt->serial.len && crt->serial.p[i] == 0) ++i;
4850+ if (i == crt->serial.len) --i;
4851+
4852+ const unsigned char *s = crt->serial.p + i;
4853+ const size_t e = (crt->serial.len - i) * 2;
4854+ if (e >= len)
4855+ return NULL;
4856+ #if 0
4857+ wpa_snprintf_hex_uppercase(serial_num, len, s, crt->serial.len-i);
4858+ #else
4859+ for (i = 0; i < e; i+=2, ++s) {
4860+ serial_num[i+0] = "0123456789ABCDEF"[(*s >> 4)];
4861+ serial_num[i+1] = "0123456789ABCDEF"[(*s & 0xF)];
4862+ }
4863+ serial_num[e] = '\0';
4864+ #endif
4865+ return serial_num;
4866+}
4867+
4868+
4869+char * tls_connection_peer_serial_num(void *tls_ctx,
4870+ struct tls_connection *conn)
4871+{
4872+ const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&conn->ssl);
4873+ if (crt == NULL)
4874+ return NULL;
4875+ size_t len = crt->serial.len * 2 + 1;
4876+ char *serial_num = os_malloc(len);
4877+ if (!serial_num)
4878+ return NULL;
4879+ return tls_mbedtls_peer_serial_num(crt, serial_num, len);
4880+}
4881+
4882+
4883+static void tls_pull_buf_reset(struct tls_connection *conn);
4884+
4885+int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
4886+{
4887+ /* Note: this function called from eap_peer_tls_reauth_init()
4888+ * for session resumption, not for connection shutdown */
4889+
4890+ if (conn == NULL)
4891+ return -1;
4892+
4893+ tls_pull_buf_reset(conn);
4894+ wpabuf_free(conn->push_buf);
4895+ conn->push_buf = NULL;
4896+ conn->established = 0;
4897+ conn->resumed = 0;
4898+ if (conn->tls_prf_type)
4899+ tls_connection_deinit_expkey(conn);
4900+
4901+ /* RFE: prepare for session resumption? (see doc in crypto/tls.h) */
4902+
4903+ return mbedtls_ssl_session_reset(&conn->ssl);
4904+}
4905+
4906+
4907+static int tls_wpabuf_resize_put_data(struct wpabuf **buf,
4908+ const unsigned char *data, size_t dlen)
4909+{
4910+ if (wpabuf_resize(buf, dlen) < 0)
4911+ return 0;
4912+ wpabuf_put_data(*buf, data, dlen);
4913+ return 1;
4914+}
4915+
4916+
4917+static int tls_pull_buf_append(struct tls_connection *conn,
4918+ const struct wpabuf *in_data)
4919+{
4920+ /*(interface does not lend itself to move semantics)*/
4921+ return tls_wpabuf_resize_put_data(&conn->pull_buf,
4922+ wpabuf_head(in_data),
4923+ wpabuf_len(in_data));
4924+}
4925+
4926+
4927+static void tls_pull_buf_reset(struct tls_connection *conn)
4928+{
4929+ /*(future: might consider reusing conn->pull_buf)*/
4930+ wpabuf_free(conn->pull_buf);
4931+ conn->pull_buf = NULL;
4932+ conn->pull_buf_offset = 0;
4933+}
4934+
4935+
4936+__attribute_cold__
4937+static void tls_pull_buf_discard(struct tls_connection *conn, const char *func)
4938+{
4939+ size_t discard = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset;
4940+ if (discard)
4941+ wpa_printf(MSG_DEBUG,
4942+ "%s - %zu bytes remaining in pull_buf; discarding",
4943+ func, discard);
4944+ tls_pull_buf_reset(conn);
4945+}
4946+
4947+
4948+static int tls_pull_func(void *ptr, unsigned char *buf, size_t len)
4949+{
4950+ struct tls_connection *conn = (struct tls_connection *) ptr;
4951+ if (conn->pull_buf == NULL)
4952+ return MBEDTLS_ERR_SSL_WANT_READ;
4953+ const size_t dlen = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset;
4954+ if (dlen == 0)
4955+ return MBEDTLS_ERR_SSL_WANT_READ;
4956+
4957+ if (len > dlen)
4958+ len = dlen;
4959+ os_memcpy(buf, wpabuf_head(conn->pull_buf)+conn->pull_buf_offset, len);
4960+
4961+ if (len == dlen) {
4962+ tls_pull_buf_reset(conn);
4963+ /*wpa_printf(MSG_DEBUG, "%s - emptied pull_buf", __func__);*/
4964+ }
4965+ else {
4966+ conn->pull_buf_offset += len;
4967+ /*wpa_printf(MSG_DEBUG, "%s - %zu bytes remaining in pull_buf",
4968+ __func__, dlen - len);*/
4969+ }
4970+ return (int)len;
4971+}
4972+
4973+
4974+static int tls_push_func(void *ptr, const unsigned char *buf, size_t len)
4975+{
4976+ struct tls_connection *conn = (struct tls_connection *) ptr;
4977+ return tls_wpabuf_resize_put_data(&conn->push_buf, buf, len)
4978+ ? (int)len
4979+ : MBEDTLS_ERR_SSL_ALLOC_FAILED;
4980+}
4981+
4982+
4983+static int
4984+tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags);
4985+
4986+
4987+static int tls_mbedtls_ssl_setup(struct tls_connection *conn)
4988+{
4989+ #if 0
4990+ /* mbedtls_ssl_setup() must be called only once */
4991+ /* If this func might be called multiple times (e.g. via set_params),
4992+ * then we should set a flag in conn that ssl was initialized */
4993+ if (conn->ssl_is_init) {
4994+ mbedtls_ssl_free(&conn->ssl);
4995+ mbedtls_ssl_init(&conn->ssl);
4996+ }
4997+ #endif
4998+
4999+ int ret = mbedtls_ssl_setup(&conn->ssl, &conn->tls_conf->conf);
5000+ if (ret != 0) {
5001+ elog(ret, "mbedtls_ssl_setup");
5002+ return -1;
5003+ }
5004+
5005+ mbedtls_ssl_set_bio(&conn->ssl, conn, tls_push_func, tls_pull_func, NULL);
5006+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
5007+ mbedtls_ssl_set_export_keys_cb(
5008+ &conn->ssl, tls_connection_export_keys_cb, conn);
5009+ #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
5010+ mbedtls_ssl_conf_export_keys_ext_cb(
5011+ &conn->tls_conf->conf, tls_connection_export_keys_cb, conn);
5012+ #endif
5013+ if (conn->verify_peer)
5014+ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn);
5015+
5016+ return 0;
5017+}
5018+
5019+
5020+static int tls_mbedtls_data_is_pem(const u8 *data)
5021+{
5022+ return (NULL != os_strstr((char *)data, "-----"));
5023+}
5024+
5025+
5026+static void tls_mbedtls_set_allowed_tls_vers(struct tls_conf *tls_conf,
5027+ mbedtls_ssl_config *conf)
5028+{
5029+ #if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
5030+ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_3;
5031+ #endif
5032+
5033+ /* unconditionally require TLSv1.2+ for TLS_CONN_SUITEB */
5034+ if (tls_conf->flags & TLS_CONN_SUITEB) {
5035+ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_0;
5036+ tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_1;
5037+ }
5038+
5039+ const unsigned int flags = tls_conf->flags;
5040+
5041+ /* attempt to map flags to min and max TLS protocol version */
5042+
5043+ int min = (flags & TLS_CONN_DISABLE_TLSv1_0)
5044+ ? (flags & TLS_CONN_DISABLE_TLSv1_1)
5045+ ? (flags & TLS_CONN_DISABLE_TLSv1_2)
5046+ ? (flags & TLS_CONN_DISABLE_TLSv1_3)
5047+ ? 4
5048+ : 3
5049+ : 2
5050+ : 1
5051+ : 0;
5052+
5053+ int max = (flags & TLS_CONN_DISABLE_TLSv1_3)
5054+ ? (flags & TLS_CONN_DISABLE_TLSv1_2)
5055+ ? (flags & TLS_CONN_DISABLE_TLSv1_1)
5056+ ? (flags & TLS_CONN_DISABLE_TLSv1_0)
5057+ ? -1
5058+ : 0
5059+ : 1
5060+ : 2
5061+ : 3;
5062+
5063+ if ((flags & TLS_CONN_ENABLE_TLSv1_2) && min > 2) min = 2;
5064+ if ((flags & TLS_CONN_ENABLE_TLSv1_1) && min > 1) min = 1;
5065+ if ((flags & TLS_CONN_ENABLE_TLSv1_0) && min > 0) min = 0;
5066+ if (max < min) {
5067+ emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring");
5068+ return;
5069+ }
5070+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
5071+ /* mbed TLS 3.0.0 removes support for protocols < TLSv1.2 */
5072+ if (min < 2 || max < 2) {
5073+ emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring");
5074+ if (min < 2) min = 2;
5075+ if (max < 2) max = 2;
5076+ }
5077+ #endif
5078+
5079+ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */
5080+ /* MBEDTLS_SSL_VERSION_TLS1_2 = 0x0303 *//*!< (D)TLS 1.2 */
5081+ /* MBEDTLS_SSL_VERSION_TLS1_3 = 0x0304 *//*!< (D)TLS 1.3 */
5082+ min = (min == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3;
5083+ max = (max == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3;
5084+ mbedtls_ssl_conf_min_tls_version(conf, min);
5085+ mbedtls_ssl_conf_max_tls_version(conf, max);
5086+ #else
5087+ #ifndef MBEDTLS_SSL_MINOR_VERSION_4
5088+ if (min == 3) min = 2;
5089+ if (max == 3) max = 2;
5090+ #endif
5091+ /* MBEDTLS_SSL_MINOR_VERSION_0 0 *//*!< SSL v3.0 */
5092+ /* MBEDTLS_SSL_MINOR_VERSION_1 1 *//*!< TLS v1.0 */
5093+ /* MBEDTLS_SSL_MINOR_VERSION_2 2 *//*!< TLS v1.1 */
5094+ /* MBEDTLS_SSL_MINOR_VERSION_3 3 *//*!< TLS v1.2 */
5095+ /* MBEDTLS_SSL_MINOR_VERSION_4 4 *//*!< TLS v1.3 */
5096+ mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, min+1);
5097+ mbedtls_ssl_conf_max_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, max+1);
5098+ #endif
5099+}
5100+
5101+
5102+__attribute_noinline__
5103+static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n);
5104+
5105+
5106+static int
5107+tls_mbedtls_set_dhparams(struct tls_conf *tls_conf, const char *dh_file)
5108+{
5109+ size_t len;
5110+ u8 *data;
5111+ if (tls_mbedtls_readfile(dh_file, &data, &len))
5112+ return 0;
5113+
5114+ /* parse only if DH parameters if in PEM format */
5115+ if (tls_mbedtls_data_is_pem(data)
5116+ && NULL == os_strstr((char *)data, "-----BEGIN DH PARAMETERS-----")) {
5117+ if (os_strstr((char *)data, "-----BEGIN DSA PARAMETERS-----"))
5118+ wpa_printf(MSG_WARNING, "DSA parameters not handled (%s)", dh_file);
5119+ else
5120+ wpa_printf(MSG_WARNING, "unexpected DH param content (%s)",dh_file);
5121+ forced_memzero(data, len);
5122+ os_free(data);
5123+ return 0;
5124+ }
5125+
5126+ /* mbedtls_dhm_parse_dhm() expects "-----BEGIN DH PARAMETERS-----" if PEM */
5127+ mbedtls_dhm_context dhm;
5128+ mbedtls_dhm_init(&dhm);
5129+ int rc = mbedtls_dhm_parse_dhm(&dhm, data, len);
5130+ if (0 == rc)
5131+ rc = mbedtls_ssl_conf_dh_param_ctx(&tls_conf->conf, &dhm);
5132+ if (0 != rc)
5133+ elog(rc, dh_file);
5134+ mbedtls_dhm_free(&dhm);
5135+
5136+ forced_memzero(data, len);
5137+ os_free(data);
5138+ return (0 == rc);
5139+}
5140+
5141+
5142+/* reference: lighttpd src/mod_mbedtls.c:mod_mbedtls_ssl_append_curve()
5143+ * (same author: gstrauss@gluelogic.com; same license: BSD-3-Clause) */
5144+#if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */
5145+static int
5146+tls_mbedtls_append_curve (mbedtls_ecp_group_id *ids, int nids, int idsz, const mbedtls_ecp_group_id id)
5147+{
5148+ if (1 >= idsz - (nids + 1)) {
5149+ emsg(MSG_ERROR, "error: too many curves during list expand");
5150+ return -1;
5151+ }
5152+ ids[++nids] = id;
5153+ return nids;
5154+}
5155+
5156+
5157+static int
5158+tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist)
5159+{
5160+ mbedtls_ecp_group_id ids[512];
5161+ int nids = -1;
5162+ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1);
5163+ const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list();
5164+
5165+ for (const char *e = curvelist-1; e; ) {
5166+ const char * const n = e+1;
5167+ e = os_strchr(n, ':');
5168+ size_t len = e ? (size_t)(e - n) : os_strlen(n);
5169+ mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
5170+ switch (len) {
5171+ case 5:
5172+ if (0 == os_memcmp("P-521", n, 5))
5173+ grp_id = MBEDTLS_ECP_DP_SECP521R1;
5174+ else if (0 == os_memcmp("P-384", n, 5))
5175+ grp_id = MBEDTLS_ECP_DP_SECP384R1;
5176+ else if (0 == os_memcmp("P-256", n, 5))
5177+ grp_id = MBEDTLS_ECP_DP_SECP256R1;
5178+ break;
5179+ case 6:
5180+ if (0 == os_memcmp("BP-521", n, 6))
5181+ grp_id = MBEDTLS_ECP_DP_BP512R1;
5182+ else if (0 == os_memcmp("BP-384", n, 6))
5183+ grp_id = MBEDTLS_ECP_DP_BP384R1;
5184+ else if (0 == os_memcmp("BP-256", n, 6))
5185+ grp_id = MBEDTLS_ECP_DP_BP256R1;
5186+ break;
5187+ default:
5188+ break;
5189+ }
5190+ if (grp_id != MBEDTLS_ECP_DP_NONE) {
5191+ nids = tls_mbedtls_append_curve(ids, nids, idsz, grp_id);
5192+ if (-1 == nids) return 0;
5193+ continue;
5194+ }
5195+ /* similar to mbedtls_ecp_curve_info_from_name() */
5196+ const mbedtls_ecp_curve_info *info;
5197+ for (info = curve_info; info->grp_id != MBEDTLS_ECP_DP_NONE; ++info) {
5198+ if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0')
5199+ break;
5200+ }
5201+ if (info->grp_id == MBEDTLS_ECP_DP_NONE) {
5202+ wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n);
5203+ return 0;
5204+ }
5205+
5206+ nids = tls_mbedtls_append_curve(ids, nids, idsz, info->grp_id);
5207+ if (-1 == nids) return 0;
5208+ }
5209+
5210+ /* mod_openssl configures "prime256v1" if curve list not specified,
5211+ * but mbedtls provides a list of supported curves if not explicitly set */
5212+ if (-1 == nids) return 1; /* empty list; no-op */
5213+
5214+ ids[++nids] = MBEDTLS_ECP_DP_NONE; /* terminate list */
5215+ ++nids;
5216+
5217+ /* curves list must be persistent for lifetime of mbedtls_ssl_config */
5218+ tls_conf->curves = os_malloc(nids * sizeof(mbedtls_ecp_group_id));
5219+ if (tls_conf->curves == NULL)
5220+ return 0;
5221+ os_memcpy(tls_conf->curves, ids, nids * sizeof(mbedtls_ecp_group_id));
5222+
5223+ mbedtls_ssl_conf_curves(&tls_conf->conf, tls_conf->curves);
5224+ return 1;
5225+}
5226+#else
5227+static int
5228+tls_mbedtls_append_curve (uint16_t *ids, int nids, int idsz, const uint16_t id)
5229+{
5230+ if (1 >= idsz - (nids + 1)) {
5231+ emsg(MSG_ERROR, "error: too many curves during list expand");
5232+ return -1;
5233+ }
5234+ ids[++nids] = id;
5235+ return nids;
5236+}
5237+
5238+
5239+static int
5240+tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist)
5241+{
5242+ /* TLS Supported Groups (renamed from "EC Named Curve Registry")
5243+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
5244+ */
5245+ uint16_t ids[512];
5246+ int nids = -1;
5247+ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1);
5248+ const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list();
5249+
5250+ for (const char *e = curvelist-1; e; ) {
5251+ const char * const n = e+1;
5252+ e = os_strchr(n, ':');
5253+ size_t len = e ? (size_t)(e - n) : os_strlen(n);
5254+ uint16_t tls_id = 0;
5255+ switch (len) {
5256+ case 5:
5257+ if (0 == os_memcmp("P-521", n, 5))
5258+ tls_id = 25; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP521R1 */
5259+ else if (0 == os_memcmp("P-384", n, 5))
5260+ tls_id = 24; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP384R1 */
5261+ else if (0 == os_memcmp("P-256", n, 5))
5262+ tls_id = 23; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP256R1 */
5263+ break;
5264+ case 6:
5265+ if (0 == os_memcmp("BP-521", n, 6))
5266+ tls_id = 28; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP512R1 */
5267+ else if (0 == os_memcmp("BP-384", n, 6))
5268+ tls_id = 27; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP384R1 */
5269+ else if (0 == os_memcmp("BP-256", n, 6))
5270+ tls_id = 26; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP256R1 */
5271+ break;
5272+ default:
5273+ break;
5274+ }
5275+ if (tls_id != 0) {
5276+ nids = tls_mbedtls_append_curve(ids, nids, idsz, tls_id);
5277+ if (-1 == nids) return 0;
5278+ continue;
5279+ }
5280+ /* similar to mbedtls_ecp_curve_info_from_name() */
5281+ const mbedtls_ecp_curve_info *info;
5282+ for (info = curve_info; info->tls_id != 0; ++info) {
5283+ if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0')
5284+ break;
5285+ }
5286+ if (info->tls_id == 0) {
5287+ wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s",(int)len,n);
5288+ return 0;
5289+ }
5290+
5291+ nids = tls_mbedtls_append_curve(ids, nids, idsz, info->tls_id);
5292+ if (-1 == nids) return 0;
5293+ }
5294+
5295+ /* mod_openssl configures "prime256v1" if curve list not specified,
5296+ * but mbedtls provides a list of supported curves if not explicitly set */
5297+ if (-1 == nids) return 1; /* empty list; no-op */
5298+
5299+ ids[++nids] = 0; /* terminate list */
5300+ ++nids;
5301+
5302+ /* curves list must be persistent for lifetime of mbedtls_ssl_config */
5303+ tls_conf->curves = os_malloc(nids * sizeof(uint16_t));
5304+ if (tls_conf->curves == NULL)
5305+ return 0;
5306+ os_memcpy(tls_conf->curves, ids, nids * sizeof(uint16_t));
5307+
5308+ mbedtls_ssl_conf_groups(&tls_conf->conf, tls_conf->curves);
5309+ return 1;
5310+}
5311+#endif /* MBEDTLS_VERSION_NUMBER >= 0x03010000 */ /* mbedtls 3.1.0 */
5312+
5313+
5314+/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */
5315+static const int suite_AES_256_ephemeral[] = {
5316+ /* All AES-256 ephemeral suites */
5317+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
5318+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
5319+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
5320+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
5321+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
5322+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
5323+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
5324+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
5325+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
5326+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
5327+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
5328+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
5329+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8
5330+};
5331+
5332+/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */
5333+static const int suite_AES_128_ephemeral[] = {
5334+ /* All AES-128 ephemeral suites */
5335+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
5336+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
5337+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
5338+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
5339+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
5340+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
5341+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
5342+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
5343+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
5344+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
5345+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
5346+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
5347+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8
5348+};
5349+
5350+/* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */
5351+/* HIGH cipher list (mapped from openssl list to mbedtls) */
5352+static const int suite_HIGH[] = {
5353+ MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
5354+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
5355+ MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
5356+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
5357+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
5358+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
5359+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
5360+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
5361+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
5362+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
5363+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
5364+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
5365+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
5366+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
5367+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
5368+ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8,
5369+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
5370+ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
5371+ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
5372+ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
5373+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
5374+ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
5375+ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
5376+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
5377+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
5378+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
5379+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
5380+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
5381+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
5382+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
5383+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
5384+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
5385+ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
5386+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
5387+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
5388+ MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
5389+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
5390+ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
5391+ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
5392+ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
5393+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
5394+ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
5395+ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
5396+ MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
5397+ MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
5398+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
5399+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
5400+ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
5401+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
5402+ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
5403+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
5404+ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
5405+ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
5406+ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
5407+ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
5408+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
5409+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
5410+ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
5411+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
5412+ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
5413+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
5414+ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
5415+ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
5416+ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
5417+ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
5418+ MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
5419+ MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
5420+ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
5421+ MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
5422+ MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8,
5423+ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
5424+ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
5425+ MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
5426+ MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
5427+ MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
5428+ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
5429+ MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
5430+ MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8,
5431+ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
5432+ MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
5433+ MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
5434+ MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
5435+ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
5436+ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
5437+ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
5438+ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
5439+ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
5440+ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
5441+ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
5442+ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
5443+ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
5444+ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
5445+ MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
5446+ MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
5447+ MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
5448+ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
5449+ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
5450+ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
5451+ MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
5452+ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
5453+ MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
5454+ MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
5455+ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
5456+ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
5457+ MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
5458+ MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
5459+ MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256
5460+};
5461+
5462+
5463+__attribute_noinline__
5464+static int
5465+tls_mbedtls_append_ciphersuite (int *ids, int nids, int idsz, const int *x, int xsz)
5466+{
5467+ if (xsz >= idsz - (nids + 1)) {
5468+ emsg(MSG_ERROR, "error: too many ciphers during list expand");
5469+ return -1;
5470+ }
5471+
5472+ for (int i = 0; i < xsz; ++i)
5473+ ids[++nids] = x[i];
5474+
5475+ return nids;
5476+}
5477+
5478+
5479+static int
5480+tls_mbedtls_translate_ciphername(int id, char *buf, size_t buflen)
5481+{
5482+ const mbedtls_ssl_ciphersuite_t *info =
5483+ mbedtls_ssl_ciphersuite_from_id(id);
5484+ if (info == NULL)
5485+ return 0;
5486+ const char *name = mbedtls_ssl_ciphersuite_get_name(info);
5487+ const size_t len = os_strlen(name);
5488+ if (len == 7 && 0 == os_memcmp(name, "unknown", 7))
5489+ return 0;
5490+ if (len >= buflen)
5491+ return 0;
5492+ os_strlcpy(buf, name, buflen);
5493+
5494+ /* attempt to translate mbedtls string to openssl string
5495+ * (some heuristics; incomplete) */
5496+ size_t i = 0, j = 0;
5497+ if (buf[0] == 'T') {
5498+ if (os_strncmp(buf, "TLS1-3-", 7) == 0) {
5499+ buf[3] = '-';
5500+ j = 4; /* remove "1-3" from "TLS1-3-" prefix */
5501+ i = 7;
5502+ }
5503+ else if (os_strncmp(buf, "TLS-", 4) == 0)
5504+ i = 4; /* remove "TLS-" prefix */
5505+ }
5506+ for (; buf[i]; ++i) {
5507+ if (buf[i] == '-') {
5508+ if (i >= 3) {
5509+ if (0 == os_memcmp(buf+i-3, "AES", 3))
5510+ continue; /* "AES-" -> "AES" */
5511+ }
5512+ if (i >= 4) {
5513+ if (0 == os_memcmp(buf+i-4, "WITH", 4)) {
5514+ j -= 4; /* remove "WITH-" */
5515+ continue;
5516+ }
5517+ }
5518+ }
5519+ buf[j++] = buf[i];
5520+ }
5521+ buf[j] = '\0';
5522+
5523+ return j;
5524+}
5525+
5526+
5527+__attribute_noinline__
5528+static int
5529+tls_mbedtls_set_ciphersuites(struct tls_conf *tls_conf, int *ids, int nids)
5530+{
5531+ /* ciphersuites list must be persistent for lifetime of mbedtls_ssl_config*/
5532+ os_free(tls_conf->ciphersuites);
5533+ tls_conf->ciphersuites = os_malloc(nids * sizeof(int));
5534+ if (tls_conf->ciphersuites == NULL)
5535+ return 0;
5536+ os_memcpy(tls_conf->ciphersuites, ids, nids * sizeof(int));
5537+ mbedtls_ssl_conf_ciphersuites(&tls_conf->conf, tls_conf->ciphersuites);
5538+ return 1;
5539+}
5540+
5541+
5542+static int
5543+tls_mbedtls_set_ciphers(struct tls_conf *tls_conf, const char *ciphers)
5544+{
5545+ char buf[64];
5546+ int ids[512];
5547+ int nids = -1;
5548+ const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1);
5549+ const char *next;
5550+ size_t blen, clen;
5551+ do {
5552+ next = os_strchr(ciphers, ':');
5553+ clen = next ? (size_t)(next - ciphers) : os_strlen(ciphers);
5554+ if (!clen)
5555+ continue;
5556+
5557+ /* special-case a select set of openssl group names for hwsim tests */
5558+ /* (review; remove excess code if tests are not run for non-OpenSSL?) */
5559+ if (clen == 9 && os_memcmp(ciphers, "SUITEB192", 9) == 0) {
5560+ static int ssl_preset_suiteb192_ciphersuites[] = {
5561+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
5562+ 0
5563+ };
5564+ return tls_mbedtls_set_ciphersuites(tls_conf,
5565+ ssl_preset_suiteb192_ciphersuites,
5566+ 2);
5567+ }
5568+ if (clen == 9 && os_memcmp(ciphers, "SUITEB128", 9) == 0) {
5569+ static int ssl_preset_suiteb128_ciphersuites[] = {
5570+ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
5571+ 0
5572+ };
5573+ return tls_mbedtls_set_ciphersuites(tls_conf,
5574+ ssl_preset_suiteb128_ciphersuites,
5575+ 2);
5576+ }
5577+ if (clen == 7 && os_memcmp(ciphers, "DEFAULT", 7) == 0)
5578+ continue;
5579+ if (clen == 6 && os_memcmp(ciphers, "AES128", 6) == 0) {
5580+ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz,
5581+ suite_AES_128_ephemeral,
5582+ (int)ARRAY_SIZE(suite_AES_128_ephemeral));
5583+ if (nids == -1)
5584+ return 0;
5585+ continue;
5586+ }
5587+ if (clen == 6 && os_memcmp(ciphers, "AES256", 6) == 0) {
5588+ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz,
5589+ suite_AES_256_ephemeral,
5590+ (int)ARRAY_SIZE(suite_AES_256_ephemeral));
5591+ if (nids == -1)
5592+ return 0;
5593+ continue;
5594+ }
5595+ if (clen == 4 && os_memcmp(ciphers, "HIGH", 4) == 0) {
5596+ nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_HIGH,
5597+ (int)ARRAY_SIZE(suite_HIGH));
5598+ if (nids == -1)
5599+ return 0;
5600+ continue;
5601+ }
5602+ /* ignore anonymous cipher group names (?not supported by mbedtls?) */
5603+ if (clen == 4 && os_memcmp(ciphers, "!ADH", 4) == 0)
5604+ continue;
5605+ if (clen == 6 && os_memcmp(ciphers, "-aECDH", 6) == 0)
5606+ continue;
5607+ if (clen == 7 && os_memcmp(ciphers, "-aECDSA", 7) == 0)
5608+ continue;
5609+
5610+ /* attempt to match mbedtls cipher names
5611+ * nb: does not support openssl group names or list manipulation syntax
5612+ * (alt: could copy almost 1200 lines (!!!) of lighttpd mod_mbedtls.c
5613+ * mod_mbedtls_ssl_conf_ciphersuites() to translate strings)
5614+ * note: not efficient to rewrite list for each ciphers entry,
5615+ * but this code is expected to run only at startup
5616+ */
5617+ const int *list = mbedtls_ssl_list_ciphersuites();
5618+ for (; *list; ++list) {
5619+ blen = tls_mbedtls_translate_ciphername(*list,buf,sizeof(buf));
5620+ if (!blen)
5621+ continue;
5622+
5623+ /* matching heuristics additional to translate_ciphername above */
5624+ if (blen == clen+4) {
5625+ char *cbc = os_strstr(buf, "CBC-");
5626+ if (cbc) {
5627+ os_memmove(cbc, cbc+4, blen-(cbc+4-buf)+1); /*(w/ '\0')*/
5628+ blen -= 4;
5629+ }
5630+ }
5631+ if (blen >= clen && os_memcmp(ciphers, buf, clen) == 0
5632+ && (blen == clen
5633+ || (blen == clen+7 && os_memcmp(buf+clen, "-SHA256", 7)))) {
5634+ if (1 >= idsz - (nids + 1)) {
5635+ emsg(MSG_ERROR,
5636+ "error: too many ciphers during list expand");
5637+ return 0;
5638+ }
5639+ ids[++nids] = *list;
5640+ break;
5641+ }
5642+ }
5643+ if (*list == 0) {
5644+ wpa_printf(MSG_ERROR,
5645+ "MTLS: unrecognized cipher: %.*s", (int)clen, ciphers);
5646+ return 0;
5647+ }
5648+ } while ((ciphers = next ? next+1 : NULL));
5649+
5650+ if (-1 == nids) return 1; /* empty list; no-op */
5651+
5652+ ids[++nids] = 0; /* terminate list */
5653+ ++nids;
5654+
5655+ return tls_mbedtls_set_ciphersuites(tls_conf, ids, nids);
5656+}
5657+
5658+
5659+__attribute_noinline__
5660+static int tls_mbedtls_set_item(char **config_item, const char *item)
5661+{
5662+ os_free(*config_item);
5663+ *config_item = NULL;
5664+ return item ? (*config_item = os_strdup(item)) != NULL : 1;
5665+}
5666+
5667+
5668+static int tls_connection_set_subject_match(struct tls_conf *tls_conf,
5669+ const struct tls_connection_params *params)
5670+{
5671+ int rc = 1;
5672+ rc &= tls_mbedtls_set_item(&tls_conf->subject_match,
5673+ params->subject_match);
5674+ rc &= tls_mbedtls_set_item(&tls_conf->altsubject_match,
5675+ params->altsubject_match);
5676+ rc &= tls_mbedtls_set_item(&tls_conf->suffix_match,
5677+ params->suffix_match);
5678+ rc &= tls_mbedtls_set_item(&tls_conf->domain_match,
5679+ params->domain_match);
5680+ rc &= tls_mbedtls_set_item(&tls_conf->check_cert_subject,
5681+ params->check_cert_subject);
5682+ return rc;
5683+}
5684+
5685+
5686+/* duplicated in crypto_mbedtls.c:crypto_mbedtls_readfile()*/
5687+__attribute_noinline__
5688+static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n)
5689+{
5690+ #if 0 /* #ifdef MBEDTLS_FS_IO */
5691+ /*(includes +1 for '\0' needed by mbedtls PEM parsing funcs)*/
5692+ if (mbedtls_pk_load_file(path, (unsigned char **)buf, n) != 0) {
5693+ wpa_printf(MSG_ERROR, "error: mbedtls_pk_load_file %s", path);
5694+ return -1;
5695+ }
5696+ #else
5697+ /*(use os_readfile() so that we can use os_free()
5698+ *(if we use mbedtls_pk_load_file() above, macros prevent calling free()
5699+ * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free()
5700+ * on buf aborts in tests if buf not allocated via os_malloc())*/
5701+ *buf = (u8 *)os_readfile(path, n);
5702+ if (!*buf) {
5703+ wpa_printf(MSG_ERROR, "error: os_readfile %s", path);
5704+ return -1;
5705+ }
5706+ u8 *buf0 = os_realloc(*buf, *n+1);
5707+ if (!buf0) {
5708+ bin_clear_free(*buf, *n);
5709+ *buf = NULL;
5710+ return -1;
5711+ }
5712+ buf0[(*n)++] = '\0';
5713+ *buf = buf0;
5714+ #endif
5715+ return 0;
5716+}
5717+
5718+
5719+static int tls_mbedtls_set_crl(struct tls_conf *tls_conf, const u8 *data, size_t len)
5720+{
5721+ /* do not use mbedtls_x509_crl_parse() on PEM unless it contains CRL */
5722+ if (len && data[len-1] == '\0'
5723+ && NULL == os_strstr((const char *)data,"-----BEGIN X509 CRL-----")
5724+ && tls_mbedtls_data_is_pem(data))
5725+ return 0;
5726+
5727+ mbedtls_x509_crl crl;
5728+ mbedtls_x509_crl_init(&crl);
5729+ int rc = mbedtls_x509_crl_parse(&crl, data, len);
5730+ if (rc < 0) {
5731+ mbedtls_x509_crl_free(&crl);
5732+ return rc == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ? 0 : rc;
5733+ }
5734+
5735+ mbedtls_x509_crl *crl_new = os_malloc(sizeof(crl));
5736+ if (crl_new == NULL) {
5737+ mbedtls_x509_crl_free(&crl);
5738+ return MBEDTLS_ERR_X509_ALLOC_FAILED;
5739+ }
5740+ os_memcpy(crl_new, &crl, sizeof(crl));
5741+
5742+ mbedtls_x509_crl *crl_old = tls_conf->crl;
5743+ tls_conf->crl = crl_new;
5744+ if (crl_old) {
5745+ mbedtls_x509_crl_free(crl_old);
5746+ os_free(crl_old);
5747+ }
5748+ return 0;
5749+}
5750+
5751+
5752+static int tls_mbedtls_set_ca(struct tls_conf *tls_conf, u8 *data, size_t len)
5753+{
5754+ /* load crt struct onto stack and then copy into tls_conf in
5755+ * order to preserve existing tls_conf value if error occurs
5756+ *
5757+ * hostapd is not threaded, or else should allocate memory and swap in
5758+ * pointer reduce race condition. (If threaded, would also need to
5759+ * keep reference count of use to avoid freeing while still in use.) */
5760+
5761+ mbedtls_x509_crt crt;
5762+ mbedtls_x509_crt_init(&crt);
5763+ int rc = mbedtls_x509_crt_parse(&crt, data, len);
5764+ if (rc < 0) {
5765+ mbedtls_x509_crt_free(&crt);
5766+ return rc;
5767+ }
5768+
5769+ mbedtls_x509_crt_free(&tls_conf->ca_cert);
5770+ os_memcpy(&tls_conf->ca_cert, &crt, sizeof(crt));
5771+ return 0;
5772+}
5773+
5774+
5775+static int tls_mbedtls_set_ca_and_crl(struct tls_conf *tls_conf, const char *ca_cert_file)
5776+{
5777+ size_t len;
5778+ u8 *data;
5779+ if (tls_mbedtls_readfile(ca_cert_file, &data, &len))
5780+ return -1;
5781+
5782+ int rc;
5783+ if (0 == (rc = tls_mbedtls_set_ca(tls_conf, data, len))
5784+ && (!tls_mbedtls_data_is_pem(data) /*skip parse for CRL if not PEM*/
5785+ || 0 == (rc = tls_mbedtls_set_crl(tls_conf, data, len)))) {
5786+ mbedtls_ssl_conf_ca_chain(&tls_conf->conf,
5787+ &tls_conf->ca_cert,
5788+ tls_conf->crl);
5789+ }
5790+ else {
5791+ elog(rc, __func__);
5792+ emsg(MSG_ERROR, ca_cert_file);
5793+ }
5794+
5795+ forced_memzero(data, len);
5796+ os_free(data);
5797+ return rc;
5798+}
5799+
5800+
5801+static void tls_mbedtls_refresh_crl(void)
5802+{
5803+ /* check for CRL refresh
5804+ * continue even if error occurs; continue with previous cert, CRL */
5805+ unsigned int crl_reload_interval = tls_ctx_global.crl_reload_interval;
5806+ const char *ca_cert_file = tls_ctx_global.ca_cert_file;
5807+ if (!crl_reload_interval || !ca_cert_file)
5808+ return;
5809+
5810+ struct os_reltime *previous = &tls_ctx_global.crl_reload_previous;
5811+ struct os_reltime now;
5812+ if (os_get_reltime(&now) != 0
5813+ || !os_reltime_expired(&now, previous, crl_reload_interval))
5814+ return;
5815+
5816+ /* Note: modifying global state is not thread-safe
5817+ * if in use by existing connections
5818+ *
5819+ * src/utils/os.h does not provide a portable stat()
5820+ * or else it would be a good idea to check mtime and size,
5821+ * and avoid reloading if file has not changed */
5822+
5823+ if (tls_mbedtls_set_ca_and_crl(tls_ctx_global.tls_conf, ca_cert_file) == 0)
5824+ *previous = now;
5825+}
5826+
5827+
5828+static int tls_mbedtls_set_ca_cert(struct tls_conf *tls_conf,
5829+ const struct tls_connection_params *params)
5830+{
5831+ if (params->ca_cert) {
5832+ if (os_strncmp(params->ca_cert, "probe://", 8) == 0) {
5833+ tls_conf->ca_cert_probe = 1;
5834+ tls_conf->has_ca_cert = 1;
5835+ return 0;
5836+ }
5837+
5838+ if (os_strncmp(params->ca_cert, "hash://", 7) == 0) {
5839+ const char *pos = params->ca_cert + 7;
5840+ if (os_strncmp(pos, "server/sha256/", 14) != 0) {
5841+ emsg(MSG_ERROR, "unsupported ca_cert hash value");
5842+ return -1;
5843+ }
5844+ pos += 14;
5845+ if (os_strlen(pos) != SHA256_DIGEST_LENGTH*2) {
5846+ emsg(MSG_ERROR, "unexpected ca_cert hash length");
5847+ return -1;
5848+ }
5849+ if (hexstr2bin(pos, tls_conf->ca_cert_hash,
5850+ SHA256_DIGEST_LENGTH) < 0) {
5851+ emsg(MSG_ERROR, "invalid ca_cert hash value");
5852+ return -1;
5853+ }
5854+ emsg(MSG_DEBUG, "checking only server certificate match");
5855+ tls_conf->verify_depth0_only = 1;
5856+ tls_conf->has_ca_cert = 1;
5857+ return 0;
5858+ }
5859+
5860+ if (tls_mbedtls_set_ca_and_crl(tls_conf, params->ca_cert) != 0)
5861+ return -1;
5862+ }
5863+ if (params->ca_cert_blob) {
5864+ size_t len = params->ca_cert_blob_len;
5865+ int is_pem = tls_mbedtls_data_is_pem(params->ca_cert_blob);
5866+ if (len && params->ca_cert_blob[len-1] != '\0' && is_pem)
5867+ ++len; /*(include '\0' in len for PEM)*/
5868+ int ret = mbedtls_x509_crt_parse(&tls_conf->ca_cert,
5869+ params->ca_cert_blob, len);
5870+ if (ret != 0) {
5871+ elog(ret, "mbedtls_x509_crt_parse");
5872+ return -1;
5873+ }
5874+ if (is_pem) { /*(ca_cert_blob in DER format contains ca cert only)*/
5875+ ret = tls_mbedtls_set_crl(tls_conf, params->ca_cert_blob, len);
5876+ if (ret != 0) {
5877+ elog(ret, "mbedtls_x509_crl_parse");
5878+ return -1;
5879+ }
5880+ }
5881+ }
5882+
5883+ if (mbedtls_x509_time_is_future(&tls_conf->ca_cert.valid_from)
5884+ || mbedtls_x509_time_is_past(&tls_conf->ca_cert.valid_to)) {
5885+ emsg(MSG_WARNING, "ca_cert expired or not yet valid");
5886+ if (params->ca_cert)
5887+ emsg(MSG_WARNING, params->ca_cert);
5888+ }
5889+
5890+ tls_conf->has_ca_cert = 1;
5891+ return 0;
5892+}
5893+
5894+
5895+static int tls_mbedtls_set_certs(struct tls_conf *tls_conf,
5896+ const struct tls_connection_params *params)
5897+{
5898+ int ret;
5899+
5900+ if (params->ca_cert || params->ca_cert_blob) {
5901+ if (tls_mbedtls_set_ca_cert(tls_conf, params) != 0)
5902+ return -1;
5903+ }
5904+ else if (params->ca_path) {
5905+ emsg(MSG_INFO, "ca_path support not implemented");
5906+ return -1;
5907+ }
5908+
5909+ if (!tls_conf->has_ca_cert)
5910+ mbedtls_ssl_conf_authmode(&tls_conf->conf, MBEDTLS_SSL_VERIFY_NONE);
5911+ else {
5912+ /* Initial setting: REQUIRED for client, OPTIONAL for server
5913+ * (see also tls_connection_set_verify()) */
5914+ tls_conf->verify_peer = (tls_ctx_global.tls_conf == NULL);
5915+ int authmode = tls_conf->verify_peer
5916+ ? MBEDTLS_SSL_VERIFY_REQUIRED
5917+ : MBEDTLS_SSL_VERIFY_OPTIONAL;
5918+ mbedtls_ssl_conf_authmode(&tls_conf->conf, authmode);
5919+ mbedtls_ssl_conf_ca_chain(&tls_conf->conf,
5920+ &tls_conf->ca_cert,
5921+ tls_conf->crl);
5922+
5923+ if (!tls_connection_set_subject_match(tls_conf, params))
5924+ return -1;
5925+ }
5926+
5927+ if (params->client_cert2) /*(yes, server_cert2 in msg below)*/
5928+ emsg(MSG_INFO, "server_cert2 support not implemented");
5929+
5930+ if (params->client_cert) {
5931+ size_t len;
5932+ u8 *data;
5933+ if (tls_mbedtls_readfile(params->client_cert, &data, &len))
5934+ return -1;
5935+ ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, data, len);
5936+ forced_memzero(data, len);
5937+ os_free(data);
5938+ }
5939+ if (params->client_cert_blob) {
5940+ size_t len = params->client_cert_blob_len;
5941+ if (len && params->client_cert_blob[len-1] != '\0'
5942+ && tls_mbedtls_data_is_pem(params->client_cert_blob))
5943+ ++len; /*(include '\0' in len for PEM)*/
5944+ ret = mbedtls_x509_crt_parse(&tls_conf->client_cert,
5945+ params->client_cert_blob, len);
5946+ }
5947+ if (params->client_cert || params->client_cert_blob) {
5948+ if (ret < 0) {
5949+ elog(ret, "mbedtls_x509_crt_parse");
5950+ if (params->client_cert)
5951+ emsg(MSG_ERROR, params->client_cert);
5952+ return -1;
5953+ }
5954+ if (mbedtls_x509_time_is_future(&tls_conf->client_cert.valid_from)
5955+ || mbedtls_x509_time_is_past(&tls_conf->client_cert.valid_to)) {
5956+ emsg(MSG_WARNING, "cert expired or not yet valid");
5957+ if (params->client_cert)
5958+ emsg(MSG_WARNING, params->client_cert);
5959+ }
5960+ tls_conf->has_client_cert = 1;
5961+ }
5962+
5963+ if (params->private_key || params->private_key_blob) {
5964+ size_t len = params->private_key_blob_len;
5965+ u8 *data;
5966+ *(const u8 **)&data = params->private_key_blob;
5967+ if (len && data[len-1] != '\0' && tls_mbedtls_data_is_pem(data))
5968+ ++len; /*(include '\0' in len for PEM)*/
5969+ if (params->private_key
5970+ && tls_mbedtls_readfile(params->private_key, &data, &len)) {
5971+ return -1;
5972+ }
5973+ const char *pwd = params->private_key_passwd;
5974+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
5975+ ret = mbedtls_pk_parse_key(&tls_conf->private_key,
5976+ data, len,
5977+ (const unsigned char *)pwd,
5978+ pwd ? os_strlen(pwd) : 0,
5979+ mbedtls_ctr_drbg_random,
5980+ tls_ctx_global.ctr_drbg);
5981+ #else
5982+ ret = mbedtls_pk_parse_key(&tls_conf->private_key,
5983+ data, len,
5984+ (const unsigned char *)pwd,
5985+ pwd ? os_strlen(pwd) : 0);
5986+ #endif
5987+ if (params->private_key) {
5988+ forced_memzero(data, len);
5989+ os_free(data);
5990+ }
5991+ if (ret < 0) {
5992+ elog(ret, "mbedtls_pk_parse_key");
5993+ return -1;
5994+ }
5995+ tls_conf->has_private_key = 1;
5996+ }
5997+
5998+ if (tls_conf->has_client_cert && tls_conf->has_private_key) {
5999+ ret = mbedtls_ssl_conf_own_cert(
6000+ &tls_conf->conf, &tls_conf->client_cert, &tls_conf->private_key);
6001+ if (ret < 0) {
6002+ elog(ret, "mbedtls_ssl_conf_own_cert");
6003+ return -1;
6004+ }
6005+ }
6006+
6007+ return 0;
6008+}
6009+
6010+
6011+/* mbedtls_x509_crt_profile_suiteb plus rsa_min_bitlen 2048 */
6012+/* (reference: see also mbedtls_x509_crt_profile_next) */
6013+/* ??? should permit SHA-512, too, and additional curves ??? */
6014+static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb128 =
6015+{
6016+ /* Only SHA-256 and 384 */
6017+ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
6018+ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
6019+ /* Only ECDSA */
6020+ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) |
6021+ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ),
6022+#if defined(MBEDTLS_ECP_C)
6023+ /* Only NIST P-256 and P-384 */
6024+ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
6025+ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
6026+#else
6027+ 0,
6028+#endif
6029+ 2048,
6030+};
6031+
6032+
6033+/* stricter than mbedtls_x509_crt_profile_suiteb */
6034+/* (reference: see also mbedtls_x509_crt_profile_next) */
6035+/* ??? should permit SHA-512, too, and additional curves ??? */
6036+static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192 =
6037+{
6038+ /* Only SHA-384 */
6039+ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
6040+ /* Only ECDSA */
6041+ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) |
6042+ MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ),
6043+#if defined(MBEDTLS_ECP_C)
6044+ /* Only NIST P-384 */
6045+ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
6046+#else
6047+ 0,
6048+#endif
6049+ 3072,
6050+};
6051+
6052+
6053+/* stricter than mbedtls_x509_crt_profile_suiteb except allow any PK alg */
6054+/* (reference: see also mbedtls_x509_crt_profile_next) */
6055+/* ??? should permit SHA-512, too, and additional curves ??? */
6056+static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192_anypk =
6057+{
6058+ /* Only SHA-384 */
6059+ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
6060+ 0xFFFFFFF, /* Any PK alg */
6061+#if defined(MBEDTLS_ECP_C)
6062+ /* Only NIST P-384 */
6063+ MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
6064+#else
6065+ 0,
6066+#endif
6067+ 3072,
6068+};
6069+
6070+
6071+static int tls_mbedtls_set_params(struct tls_conf *tls_conf,
6072+ const struct tls_connection_params *params)
6073+{
6074+ tls_conf->flags = params->flags;
6075+
6076+ if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP_ALL) {
6077+ emsg(MSG_INFO, "ocsp=3 not supported");
6078+ return -1;
6079+ }
6080+
6081+ if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP) {
6082+ emsg(MSG_INFO, "ocsp not supported");
6083+ return -1;
6084+ }
6085+
6086+ int suiteb128 = 0;
6087+ int suiteb192 = 0;
6088+ if (params->openssl_ciphers) {
6089+ if (os_strcmp(params->openssl_ciphers, "SUITEB192") == 0) {
6090+ suiteb192 = 1;
6091+ tls_conf->flags |= TLS_CONN_SUITEB;
6092+ }
6093+ if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) {
6094+ suiteb128 = 1;
6095+ tls_conf->flags |= TLS_CONN_SUITEB;
6096+ }
6097+ }
6098+
6099+ int ret = mbedtls_ssl_config_defaults(
6100+ &tls_conf->conf, tls_ctx_global.tls_conf ? MBEDTLS_SSL_IS_SERVER
6101+ : MBEDTLS_SSL_IS_CLIENT,
6102+ MBEDTLS_SSL_TRANSPORT_STREAM,
6103+ (tls_conf->flags & TLS_CONN_SUITEB) ? MBEDTLS_SSL_PRESET_SUITEB
6104+ : MBEDTLS_SSL_PRESET_DEFAULT);
6105+ if (ret != 0) {
6106+ elog(ret, "mbedtls_ssl_config_defaults");
6107+ return -1;
6108+ }
6109+
6110+ if (suiteb128) {
6111+ mbedtls_ssl_conf_cert_profile(&tls_conf->conf,
6112+ &tls_mbedtls_crt_profile_suiteb128);
6113+ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 2048);
6114+ }
6115+ else if (suiteb192) {
6116+ mbedtls_ssl_conf_cert_profile(&tls_conf->conf,
6117+ &tls_mbedtls_crt_profile_suiteb192);
6118+ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072);
6119+ }
6120+ else if (tls_conf->flags & TLS_CONN_SUITEB) {
6121+ /* treat as suiteb192 while allowing any PK algorithm */
6122+ mbedtls_ssl_conf_cert_profile(&tls_conf->conf,
6123+ &tls_mbedtls_crt_profile_suiteb192_anypk);
6124+ mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072);
6125+ }
6126+
6127+ tls_mbedtls_set_allowed_tls_vers(tls_conf, &tls_conf->conf);
6128+ ret = tls_mbedtls_set_certs(tls_conf, params);
6129+ if (ret != 0)
6130+ return -1;
6131+
6132+ if (params->dh_file
6133+ && !tls_mbedtls_set_dhparams(tls_conf, params->dh_file)) {
6134+ return -1;
6135+ }
6136+
6137+ if (params->openssl_ecdh_curves
6138+ && !tls_mbedtls_set_curves(tls_conf, params->openssl_ecdh_curves)) {
6139+ return -1;
6140+ }
6141+
6142+ if (params->openssl_ciphers) {
6143+ if (!tls_mbedtls_set_ciphers(tls_conf, params->openssl_ciphers))
6144+ return -1;
6145+ }
6146+ else if (tls_conf->flags & TLS_CONN_SUITEB) {
6147+ /* special-case a select set of ciphers for hwsim tests */
6148+ if (!tls_mbedtls_set_ciphers(tls_conf,
6149+ (tls_conf->flags & TLS_CONN_SUITEB_NO_ECDH)
6150+ ? "DHE-RSA-AES256-GCM-SHA384"
6151+ : "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384"))
6152+ return -1;
6153+ }
6154+
6155+ return 0;
6156+}
6157+
6158+
6159+int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
6160+ const struct tls_connection_params *params)
6161+{
6162+ if (conn == NULL || params == NULL)
6163+ return -1;
6164+
6165+ tls_conf_deinit(conn->tls_conf);
6166+ struct tls_conf *tls_conf = conn->tls_conf = tls_conf_init(tls_ctx);
6167+ if (tls_conf == NULL)
6168+ return -1;
6169+
6170+ if (tls_ctx_global.tls_conf) {
6171+ tls_conf->check_crl = tls_ctx_global.tls_conf->check_crl;
6172+ tls_conf->check_crl_strict = tls_ctx_global.tls_conf->check_crl_strict;
6173+ /*(tls_openssl.c inherits check_cert_subject from global conf)*/
6174+ if (tls_ctx_global.tls_conf->check_cert_subject) {
6175+ tls_conf->check_cert_subject =
6176+ os_strdup(tls_ctx_global.tls_conf->check_cert_subject);
6177+ if (tls_conf->check_cert_subject == NULL)
6178+ return -1;
6179+ }
6180+ }
6181+
6182+ if (tls_mbedtls_set_params(tls_conf, params) != 0)
6183+ return -1;
6184+ conn->verify_peer = tls_conf->verify_peer;
6185+
6186+ return tls_mbedtls_ssl_setup(conn);
6187+}
6188+
6189+
6190+#ifdef TLS_MBEDTLS_SESSION_TICKETS
6191+
6192+static int tls_mbedtls_clienthello_session_ticket_prep (struct tls_connection *conn,
6193+ const u8 *data, size_t len)
6194+{
6195+ if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)
6196+ return -1;
6197+ if (conn->clienthello_session_ticket)
6198+ tls_connection_deinit_clienthello_session_ticket(conn);
6199+ if (len) {
6200+ conn->clienthello_session_ticket = mbedtls_calloc(1, len);
6201+ if (conn->clienthello_session_ticket == NULL)
6202+ return -1;
6203+ conn->clienthello_session_ticket_len = len;
6204+ os_memcpy(conn->clienthello_session_ticket, data, len);
6205+ }
6206+ return 0;
6207+}
6208+
6209+
6210+static void tls_mbedtls_clienthello_session_ticket_set (struct tls_connection *conn)
6211+{
6212+ mbedtls_ssl_session *sess = conn->ssl.MBEDTLS_PRIVATE(session_negotiate);
6213+ if (sess->MBEDTLS_PRIVATE(ticket)) {
6214+ mbedtls_platform_zeroize(sess->MBEDTLS_PRIVATE(ticket),
6215+ sess->MBEDTLS_PRIVATE(ticket_len));
6216+ mbedtls_free(sess->MBEDTLS_PRIVATE(ticket));
6217+ }
6218+ sess->MBEDTLS_PRIVATE(ticket) = conn->clienthello_session_ticket;
6219+ sess->MBEDTLS_PRIVATE(ticket_len) = conn->clienthello_session_ticket_len;
6220+ sess->MBEDTLS_PRIVATE(ticket_lifetime) = 86400;/* XXX: can hint be 0? */
6221+
6222+ conn->clienthello_session_ticket = NULL;
6223+ conn->clienthello_session_ticket_len = 0;
6224+}
6225+
6226+
6227+static int tls_mbedtls_ssl_ticket_write(void *p_ticket,
6228+ const mbedtls_ssl_session *session,
6229+ unsigned char *start,
6230+ const unsigned char *end,
6231+ size_t *tlen,
6232+ uint32_t *lifetime)
6233+{
6234+ struct tls_connection *conn = p_ticket;
6235+ if (conn && conn->session_ticket_cb) {
6236+ /* see tls_mbedtls_clienthello_session_ticket_prep() */
6237+ /* see tls_mbedtls_clienthello_session_ticket_set() */
6238+ return 0;
6239+ }
6240+
6241+ return mbedtls_ssl_ticket_write(&tls_ctx_global.ticket_ctx,
6242+ session, start, end, tlen, lifetime);
6243+}
6244+
6245+
6246+static int tls_mbedtls_ssl_ticket_parse(void *p_ticket,
6247+ mbedtls_ssl_session *session,
6248+ unsigned char *buf,
6249+ size_t len)
6250+{
6251+ /* XXX: TODO: not implemented in client;
6252+ * mbedtls_ssl_conf_session_tickets_cb() callbacks only for TLS server*/
6253+
6254+ if (len == 0)
6255+ return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6256+
6257+ struct tls_connection *conn = p_ticket;
6258+ if (conn && conn->session_ticket_cb) {
6259+ /* XXX: have random and secret been initialized yet?
6260+ * or must keys first be exported?
6261+ * EAP-FAST uses all args, EAP-TEAP only uses secret */
6262+ struct tls_random data;
6263+ if (tls_connection_get_random(NULL, conn, &data) != 0)
6264+ return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
6265+ int ret =
6266+ conn->session_ticket_cb(conn->session_ticket_cb_ctx,
6267+ buf, len,
6268+ data.client_random,
6269+ data.server_random,
6270+ conn->expkey_secret);
6271+ if (ret == 1) {
6272+ conn->resumed = 1;
6273+ return 0;
6274+ }
6275+ emsg(MSG_ERROR, "EAP session ticket ext not implemented");
6276+ return MBEDTLS_ERR_SSL_INVALID_MAC;
6277+ /*(non-zero return used for mbedtls debug logging)*/
6278+ }
6279+
6280+ /* XXX: TODO always use tls_mbedtls_ssl_ticket_parse() for callback? */
6281+ int rc = mbedtls_ssl_ticket_parse(&tls_ctx_global.ticket_ctx,
6282+ session, buf, len);
6283+ if (conn)
6284+ conn->resumed = (rc == 0);
6285+ return rc;
6286+}
6287+
6288+#endif /* TLS_MBEDTLS_SESSION_TICKETS */
6289+
6290+
6291+__attribute_cold__
6292+int tls_global_set_params(void *tls_ctx,
6293+ const struct tls_connection_params *params)
6294+{
6295+ /* XXX: why might global_set_params be called more than once? */
6296+ if (tls_ctx_global.tls_conf)
6297+ tls_conf_deinit(tls_ctx_global.tls_conf);
6298+ tls_ctx_global.tls_conf = tls_conf_init(tls_ctx);
6299+ if (tls_ctx_global.tls_conf == NULL)
6300+ return -1;
6301+
6302+ #ifdef MBEDTLS_SSL_SESSION_TICKETS
6303+ #ifdef MBEDTLS_SSL_TICKET_C
6304+ if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET))
6305+ #ifdef TLS_MBEDTLS_SESSION_TICKETS
6306+ mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf,
6307+ tls_mbedtls_ssl_ticket_write,
6308+ tls_mbedtls_ssl_ticket_parse,
6309+ NULL);
6310+ #else
6311+ mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf,
6312+ mbedtls_ssl_ticket_write,
6313+ mbedtls_ssl_ticket_parse,
6314+ &tls_ctx_global.ticket_ctx);
6315+ #endif
6316+ #endif
6317+ #endif
6318+
6319+ os_free(tls_ctx_global.ocsp_stapling_response);
6320+ tls_ctx_global.ocsp_stapling_response = NULL;
6321+ if (params->ocsp_stapling_response)
6322+ tls_ctx_global.ocsp_stapling_response =
6323+ os_strdup(params->ocsp_stapling_response);
6324+
6325+ os_free(tls_ctx_global.ca_cert_file);
6326+ tls_ctx_global.ca_cert_file = NULL;
6327+ if (params->ca_cert)
6328+ tls_ctx_global.ca_cert_file = os_strdup(params->ca_cert);
6329+ return tls_mbedtls_set_params(tls_ctx_global.tls_conf, params);
6330+}
6331+
6332+
6333+int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
6334+{
6335+ tls_ctx_global.tls_conf->check_crl = check_crl;
6336+ tls_ctx_global.tls_conf->check_crl_strict = strict; /*(time checks)*/
6337+ return 0;
6338+}
6339+
6340+
6341+int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
6342+ int verify_peer, unsigned int flags,
6343+ const u8 *session_ctx, size_t session_ctx_len)
6344+{
6345+ /*(EAP server-side calls this from eap_server_tls_ssl_init())*/
6346+ if (conn == NULL)
6347+ return -1;
6348+
6349+ conn->tls_conf->flags |= flags;/* TODO: reprocess flags, if necessary */
6350+
6351+ int authmode;
6352+ switch (verify_peer) {
6353+ case 2: authmode = MBEDTLS_SSL_VERIFY_OPTIONAL; break;/*(eap_teap_init())*/
6354+ case 1: authmode = MBEDTLS_SSL_VERIFY_REQUIRED; break;
6355+ default: authmode = MBEDTLS_SSL_VERIFY_NONE; break;
6356+ }
6357+ mbedtls_ssl_set_hs_authmode(&conn->ssl, authmode);
6358+
6359+ if ((conn->verify_peer = (authmode != MBEDTLS_SSL_VERIFY_NONE)))
6360+ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn);
6361+ else
6362+ mbedtls_ssl_set_verify(&conn->ssl, NULL, NULL);
6363+
6364+ return 0;
6365+}
6366+
6367+
6368+#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
6369+static void tls_connection_export_keys_cb(
6370+ void *p_expkey, mbedtls_ssl_key_export_type secret_type,
6371+ const unsigned char *secret, size_t secret_len,
6372+ const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN],
6373+ const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN],
6374+ mbedtls_tls_prf_types tls_prf_type)
6375+{
6376+ struct tls_connection *conn = p_expkey;
6377+ conn->tls_prf_type = tls_prf_type;
6378+ if (!tls_prf_type)
6379+ return;
6380+ if (secret_len > sizeof(conn->expkey_secret)) {
6381+ emsg(MSG_ERROR, "tls_connection_export_keys_cb secret too long");
6382+ conn->tls_prf_type = MBEDTLS_SSL_TLS_PRF_NONE; /* 0 */
6383+ return;
6384+ }
6385+ conn->expkey_secret_len = secret_len;
6386+ os_memcpy(conn->expkey_secret, secret, secret_len);
6387+ os_memcpy(conn->expkey_randbytes,
6388+ client_random, MBEDTLS_EXPKEY_RAND_LEN);
6389+ os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN,
6390+ server_random, MBEDTLS_EXPKEY_RAND_LEN);
6391+}
6392+#elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
6393+static int tls_connection_export_keys_cb(
6394+ void *p_expkey,
6395+ const unsigned char *ms,
6396+ const unsigned char *kb,
6397+ size_t maclen,
6398+ size_t keylen,
6399+ size_t ivlen,
6400+ const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN],
6401+ const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN],
6402+ mbedtls_tls_prf_types tls_prf_type )
6403+{
6404+ struct tls_connection *conn = p_expkey;
6405+ conn->tls_prf_type = tls_prf_type;
6406+ if (!tls_prf_type)
6407+ return -1; /*(return value ignored by mbedtls)*/
6408+ conn->expkey_keyblock_size = maclen + keylen + ivlen;
6409+ conn->expkey_secret_len = MBEDTLS_EXPKEY_FIXED_SECRET_LEN;
6410+ os_memcpy(conn->expkey_secret, ms, MBEDTLS_EXPKEY_FIXED_SECRET_LEN);
6411+ os_memcpy(conn->expkey_randbytes,
6412+ client_random, MBEDTLS_EXPKEY_RAND_LEN);
6413+ os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN,
6414+ server_random, MBEDTLS_EXPKEY_RAND_LEN);
6415+ return 0;
6416+}
6417+#endif
6418+
6419+
6420+int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn,
6421+ struct tls_random *data)
6422+{
6423+ if (!conn || !conn->tls_prf_type)
6424+ return -1;
6425+ data->client_random = conn->expkey_randbytes;
6426+ data->client_random_len = MBEDTLS_EXPKEY_RAND_LEN;
6427+ data->server_random = conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN;
6428+ data->server_random_len = MBEDTLS_EXPKEY_RAND_LEN;
6429+ return 0;
6430+}
6431+
6432+
6433+int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
6434+ const char *label, const u8 *context,
6435+ size_t context_len, u8 *out, size_t out_len)
6436+{
6437+ /* (EAP-PEAP EAP-TLS EAP-TTLS) */
6438+ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
6439+ return (conn && conn->established && conn->tls_prf_type)
6440+ ? mbedtls_ssl_tls_prf(conn->tls_prf_type,
6441+ conn->expkey_secret, conn->expkey_secret_len, label,
6442+ conn->expkey_randbytes,
6443+ sizeof(conn->expkey_randbytes), out, out_len)
6444+ : -1;
6445+ #else
6446+ /* not implemented here for mbedtls < 2.18.0 */
6447+ return -1;
6448+ #endif
6449+}
6450+
6451+
6452+#ifdef TLS_MBEDTLS_EAP_FAST
6453+
6454+#if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
6455+/* keyblock size info is not exposed in mbed TLS 3.0.0 */
6456+/* extracted from mbedtls library/ssl_tls.c:ssl_tls12_populate_transform() */
6457+#include <mbedtls/ssl_ciphersuites.h>
6458+#include <mbedtls/cipher.h>
6459+static size_t tls_mbedtls_ssl_keyblock_size (mbedtls_ssl_context *ssl)
6460+{
6461+ #if !defined(MBEDTLS_USE_PSA_CRYPTO) /* XXX: (not extracted for PSA crypto) */
6462+ #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
6463+ if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3)
6464+ return 0; /* (calculation not extracted) */
6465+ #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
6466+
6467+ int ciphersuite = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl);
6468+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
6469+ mbedtls_ssl_ciphersuite_from_id(ciphersuite);
6470+ if (ciphersuite_info == NULL)
6471+ return 0;
6472+
6473+ const mbedtls_cipher_info_t *cipher_info =
6474+ mbedtls_cipher_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(cipher));
6475+ if (cipher_info == NULL)
6476+ return 0;
6477+
6478+ #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */
6479+ size_t keylen = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
6480+ mbedtls_cipher_mode_t mode = mbedtls_cipher_info_get_mode(cipher_info);
6481+ #else
6482+ size_t keylen = cipher_info->MBEDTLS_PRIVATE(key_bitlen) / 8;
6483+ mbedtls_cipher_mode_t mode = cipher_info->MBEDTLS_PRIVATE(mode);
6484+ #endif
6485+ #if defined(MBEDTLS_GCM_C) || \
6486+ defined(MBEDTLS_CCM_C) || \
6487+ defined(MBEDTLS_CHACHAPOLY_C)
6488+ if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM)
6489+ return keylen + 4;
6490+ else if (mode == MBEDTLS_MODE_CHACHAPOLY)
6491+ return keylen + 12;
6492+ else
6493+ #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
6494+ #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
6495+ {
6496+ const mbedtls_md_info_t *md_info =
6497+ mbedtls_md_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(mac));
6498+ if (md_info == NULL)
6499+ return 0;
6500+ size_t mac_key_len = mbedtls_md_get_size(md_info);
6501+ size_t ivlen = mbedtls_cipher_info_get_iv_size(cipher_info);
6502+ return keylen + mac_key_len + ivlen;
6503+ }
6504+ #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
6505+ #endif /* !MBEDTLS_USE_PSA_CRYPTO *//* (not extracted for PSA crypto) */
6506+ return 0;
6507+}
6508+#endif /* MBEDTLS_VERSION_NUMBER >= 0x03000000 *//* mbedtls 3.0.0 */
6509+
6510+
6511+int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
6512+ u8 *out, size_t out_len)
6513+{
6514+ /* XXX: has export keys callback been run? */
6515+ if (!conn || !conn->tls_prf_type)
6516+ return -1;
6517+
6518+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
6519+ conn->expkey_keyblock_size = tls_mbedtls_ssl_keyblock_size(&conn->ssl);
6520+ if (conn->expkey_keyblock_size == 0)
6521+ return -1;
6522+ #endif
6523+ size_t skip = conn->expkey_keyblock_size * 2;
6524+ unsigned char *tmp_out = os_malloc(skip + out_len);
6525+ if (!tmp_out)
6526+ return -1;
6527+
6528+ /* server_random and then client_random */
6529+ unsigned char seed[MBEDTLS_EXPKEY_RAND_LEN*2];
6530+ os_memcpy(seed, conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN,
6531+ MBEDTLS_EXPKEY_RAND_LEN);
6532+ os_memcpy(seed + MBEDTLS_EXPKEY_RAND_LEN, conn->expkey_randbytes,
6533+ MBEDTLS_EXPKEY_RAND_LEN);
6534+
6535+ #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
6536+ int ret = mbedtls_ssl_tls_prf(conn->tls_prf_type,
6537+ conn->expkey_secret, conn->expkey_secret_len,
6538+ "key expansion", seed, sizeof(seed),
6539+ tmp_out, skip + out_len);
6540+ if (ret == 0)
6541+ os_memcpy(out, tmp_out + skip, out_len);
6542+ #else
6543+ int ret = -1; /*(not reached if not impl; return -1 at top of func)*/
6544+ #endif
6545+
6546+ bin_clear_free(tmp_out, skip + out_len);
6547+ forced_memzero(seed, sizeof(seed));
6548+ return ret;
6549+}
6550+
6551+#endif /* TLS_MBEDTLS_EAP_FAST */
6552+
6553+
6554+__attribute_cold__
6555+static void tls_mbedtls_suiteb_handshake_alert (struct tls_connection *conn)
6556+{
6557+ /* tests/hwsim/test_suite_b.py test_suite_b_192_rsa_insufficient_dh */
6558+ if (!(conn->tls_conf->flags & TLS_CONN_SUITEB))
6559+ return;
6560+ if (tls_ctx_global.tls_conf) /*(is server; want issue event on client)*/
6561+ return;
6562+ #if 0
6563+ /*(info not available on client;
6564+ * mbed TLS library enforces dhm min bitlen in ServerKeyExchange)*/
6565+ if (MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ==
6566+ #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */
6567+ mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl)
6568+ #else
6569+ mbedtls_ssl_get_ciphersuite_id(
6570+ mbedtls_ssl_get_ciphersuite(&conn->ssl))
6571+ #endif
6572+ && mbedtls_mpi_size(&conn->tls_conf->conf.MBEDTLS_PRIVATE(dhm_P))
6573+ < 384 /*(3072/8)*/)
6574+ #endif
6575+ {
6576+ struct tls_config *init_conf = &tls_ctx_global.init_conf;
6577+ if (init_conf->event_cb) {
6578+ union tls_event_data ev;
6579+ os_memset(&ev, 0, sizeof(ev));
6580+ ev.alert.is_local = 1;
6581+ ev.alert.type = "fatal";
6582+ /*"internal error" string for tests/hwsim/test_suiteb.py */
6583+ ev.alert.description = "internal error: handshake failure";
6584+ /*ev.alert.description = "insufficient security";*/
6585+ init_conf->event_cb(init_conf->cb_ctx, TLS_ALERT, &ev);
6586+ }
6587+ }
6588+}
6589+
6590+
6591+struct wpabuf * tls_connection_handshake(void *tls_ctx,
6592+ struct tls_connection *conn,
6593+ const struct wpabuf *in_data,
6594+ struct wpabuf **appl_data)
6595+{
6596+ if (appl_data)
6597+ *appl_data = NULL;
6598+
6599+ if (in_data && wpabuf_len(in_data)) {
6600+ /*(unsure why tls_gnutls.c discards buffer contents; skip here)*/
6601+ if (conn->pull_buf && 0) /* disable; appears unwise */
6602+ tls_pull_buf_discard(conn, __func__);
6603+ if (!tls_pull_buf_append(conn, in_data))
6604+ return NULL;
6605+ }
6606+
6607+ if (conn->tls_conf == NULL) {
6608+ struct tls_connection_params params;
6609+ os_memset(&params, 0, sizeof(params));
6610+ params.openssl_ciphers =
6611+ tls_ctx_global.init_conf.openssl_ciphers;
6612+ params.flags = tls_ctx_global.tls_conf->flags;
6613+ if (tls_connection_set_params(tls_ctx, conn, &params) != 0)
6614+ return NULL;
6615+ }
6616+
6617+ if (conn->verify_peer) /*(call here might be redundant; nbd)*/
6618+ mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn);
6619+
6620+ #ifdef TLS_MBEDTLS_SESSION_TICKETS
6621+ if (conn->clienthello_session_ticket)
6622+ /*(starting handshake for EAP-FAST and EAP-TEAP)*/
6623+ tls_mbedtls_clienthello_session_ticket_set(conn);
6624+
6625+ /* (not thread-safe due to need to set userdata 'conn' for callback) */
6626+ /* (unable to use mbedtls_ssl_set_user_data_p() with mbedtls 3.2.0+
6627+ * since ticket write and parse callbacks take (mbedtls_ssl_session *)
6628+ * param instead of (mbedtls_ssl_context *) param) */
6629+ if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)
6630+ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf,
6631+ NULL, NULL, NULL);
6632+ else
6633+ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf,
6634+ tls_mbedtls_ssl_ticket_write,
6635+ tls_mbedtls_ssl_ticket_parse,
6636+ conn);
6637+ #endif
6638+
6639+ #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */
6640+ int ret = mbedtls_ssl_handshake(&conn->ssl);
6641+ #else
6642+ int ret = 0;
6643+ while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER) {
6644+ ret = mbedtls_ssl_handshake_step(&conn->ssl);
6645+ if (ret != 0)
6646+ break;
6647+ }
6648+ #endif
6649+
6650+ #ifdef TLS_MBEDTLS_SESSION_TICKETS
6651+ mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf,
6652+ tls_mbedtls_ssl_ticket_write,
6653+ tls_mbedtls_ssl_ticket_parse,
6654+ NULL);
6655+ #endif
6656+
6657+ switch (ret) {
6658+ case 0:
6659+ conn->established = 1;
6660+ if (conn->push_buf == NULL)
6661+ /* Need to return something to get final TLS ACK. */
6662+ conn->push_buf = wpabuf_alloc(0);
6663+
6664+ if (appl_data /*&& conn->pull_buf && wpabuf_len(conn->pull_buf)*/)
6665+ *appl_data = NULL; /* RFE: check for application data */
6666+ break;
6667+ case MBEDTLS_ERR_SSL_WANT_WRITE:
6668+ case MBEDTLS_ERR_SSL_WANT_READ:
6669+ case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS:
6670+ case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
6671+ if (tls_ctx_global.tls_conf /*(is server)*/
6672+ && conn->established && conn->push_buf == NULL)
6673+ /* Need to return something to trigger completion of EAP-TLS. */
6674+ conn->push_buf = wpabuf_alloc(0);
6675+ break;
6676+ default:
6677+ ++conn->failed;
6678+ switch (ret) {
6679+ case MBEDTLS_ERR_SSL_CLIENT_RECONNECT:
6680+ case MBEDTLS_ERR_NET_CONN_RESET:
6681+ case MBEDTLS_ERR_NET_SEND_FAILED:
6682+ ++conn->write_alerts;
6683+ break;
6684+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
6685+ case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:
6686+ #else
6687+ case MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE:
6688+ #endif
6689+ tls_mbedtls_suiteb_handshake_alert(conn);
6690+ /* fall through */
6691+ case MBEDTLS_ERR_NET_RECV_FAILED:
6692+ case MBEDTLS_ERR_SSL_CONN_EOF:
6693+ case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
6694+ case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
6695+ ++conn->read_alerts;
6696+ break;
6697+ default:
6698+ break;
6699+ }
6700+
6701+ ilog(ret, "mbedtls_ssl_handshake");
6702+ break;
6703+ }
6704+
6705+ struct wpabuf *out_data = conn->push_buf;
6706+ conn->push_buf = NULL;
6707+ return out_data;
6708+}
6709+
6710+
6711+struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
6712+ struct tls_connection *conn,
6713+ const struct wpabuf *in_data,
6714+ struct wpabuf **appl_data)
6715+{
6716+ conn->is_server = 1;
6717+ return tls_connection_handshake(tls_ctx, conn, in_data, appl_data);
6718+}
6719+
6720+
6721+struct wpabuf * tls_connection_encrypt(void *tls_ctx,
6722+ struct tls_connection *conn,
6723+ const struct wpabuf *in_data)
6724+{
6725+ int res = mbedtls_ssl_write(&conn->ssl,
6726+ wpabuf_head_u8(in_data), wpabuf_len(in_data));
6727+ if (res < 0) {
6728+ elog(res, "mbedtls_ssl_write");
6729+ return NULL;
6730+ }
6731+
6732+ struct wpabuf *buf = conn->push_buf;
6733+ conn->push_buf = NULL;
6734+ return buf;
6735+}
6736+
6737+
6738+struct wpabuf * tls_connection_decrypt(void *tls_ctx,
6739+ struct tls_connection *conn,
6740+ const struct wpabuf *in_data)
6741+{
6742+ int res;
6743+ struct wpabuf *out;
6744+
6745+ /*assert(in_data != NULL);*/
6746+ if (!tls_pull_buf_append(conn, in_data))
6747+ return NULL;
6748+
6749+ #if defined(MBEDTLS_ZLIB_SUPPORT) /* removed in mbedtls 3.x */
6750+ /* Add extra buffer space to handle the possibility of decrypted
6751+ * data being longer than input data due to TLS compression. */
6752+ out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
6753+ #else /* TLS compression is disabled in mbedtls 3.x */
6754+ out = wpabuf_alloc(wpabuf_len(in_data));
6755+ #endif
6756+ if (out == NULL)
6757+ return NULL;
6758+
6759+ res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(out), wpabuf_size(out));
6760+ if (res < 0) {
6761+ #if 1 /*(seems like a different error if wpabuf_len(in_data) == 0)*/
6762+ if (res == MBEDTLS_ERR_SSL_WANT_READ)
6763+ return out;
6764+ #endif
6765+ elog(res, "mbedtls_ssl_read");
6766+ wpabuf_free(out);
6767+ return NULL;
6768+ }
6769+ wpabuf_put(out, res);
6770+
6771+ return out;
6772+}
6773+
6774+
6775+int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
6776+{
6777+ /* XXX: might need to detect if session resumed from TLS session ticket
6778+ * even if not special session ticket handling for EAP-FAST, EAP-TEAP */
6779+ /* (?ssl->handshake->resume during session ticket validation?) */
6780+ return conn && conn->resumed;
6781+}
6782+
6783+
6784+#ifdef TLS_MBEDTLS_EAP_FAST
6785+int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
6786+ u8 *ciphers)
6787+{
6788+ /* ciphers is list of TLS_CIPHER_* from hostap/src/crypto/tls.h */
6789+ int ids[7];
6790+ const int idsz = (int)sizeof(ids);
6791+ int nids = -1, id;
6792+ for ( ; *ciphers != TLS_CIPHER_NONE; ++ciphers) {
6793+ switch (*ciphers) {
6794+ case TLS_CIPHER_RC4_SHA:
6795+ #ifdef MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
6796+ id = MBEDTLS_TLS_RSA_WITH_RC4_128_SHA;
6797+ break;
6798+ #else
6799+ continue; /*(not supported in mbedtls 3.x; ignore)*/
6800+ #endif
6801+ case TLS_CIPHER_AES128_SHA:
6802+ id = MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA;
6803+ break;
6804+ case TLS_CIPHER_RSA_DHE_AES128_SHA:
6805+ id = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
6806+ break;
6807+ case TLS_CIPHER_ANON_DH_AES128_SHA:
6808+ continue; /*(not supported in mbedtls; ignore)*/
6809+ case TLS_CIPHER_RSA_DHE_AES256_SHA:
6810+ id = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
6811+ break;
6812+ case TLS_CIPHER_AES256_SHA:
6813+ id = MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA;
6814+ break;
6815+ default:
6816+ return -1; /* should not happen */
6817+ }
6818+ if (++nids == idsz)
6819+ return -1; /* should not happen */
6820+ ids[nids] = id;
6821+ }
6822+ if (nids < 0)
6823+ return 0; /* nothing to do */
6824+ if (++nids == idsz)
6825+ return -1; /* should not happen */
6826+ ids[nids] = 0; /* terminate list */
6827+ ++nids;
6828+
6829+ return tls_mbedtls_set_ciphersuites(conn->tls_conf, ids, nids) ? 0 : -1;
6830+}
6831+#endif
6832+
6833+
6834+int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
6835+ char *buf, size_t buflen)
6836+{
6837+ if (conn == NULL)
6838+ return -1;
6839+ os_strlcpy(buf, mbedtls_ssl_get_version(&conn->ssl), buflen);
6840+ return buf[0] != 'u' ? 0 : -1; /*(-1 if "unknown")*/
6841+}
6842+
6843+
6844+#ifdef TLS_MBEDTLS_EAP_TEAP
6845+u16 tls_connection_get_cipher_suite(struct tls_connection *conn)
6846+{
6847+ if (conn == NULL)
6848+ return 0;
6849+ return (u16)mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl);
6850+}
6851+#endif
6852+
6853+
6854+int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
6855+ char *buf, size_t buflen)
6856+{
6857+ if (conn == NULL)
6858+ return -1;
6859+ const int id = mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl);
6860+ return tls_mbedtls_translate_ciphername(id, buf, buflen) ? 0 : -1;
6861+}
6862+
6863+
6864+#ifdef TLS_MBEDTLS_SESSION_TICKETS
6865+
6866+int tls_connection_enable_workaround(void *tls_ctx,
6867+ struct tls_connection *conn)
6868+{
6869+ /* (see comment in src/eap_peer/eap_fast.c:eap_fast_init()) */
6870+ /* XXX: is there a relevant setting for this in mbed TLS? */
6871+ /* (do we even care that much about older CBC ciphers?) */
6872+ return 0;
6873+}
6874+
6875+
6876+int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
6877+ int ext_type, const u8 *data,
6878+ size_t data_len)
6879+{
6880+ /* (EAP-FAST and EAP-TEAP) */
6881+ if (ext_type == MBEDTLS_TLS_EXT_SESSION_TICKET) /*(ext_type == 35)*/
6882+ return tls_mbedtls_clienthello_session_ticket_prep(conn, data,
6883+ data_len);
6884+
6885+ return -1;
6886+}
6887+
6888+#endif /* TLS_MBEDTLS_SESSION_TICKETS */
6889+
6890+
6891+int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
6892+{
6893+ return conn ? conn->failed : -1;
6894+}
6895+
6896+
6897+int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
6898+{
6899+ return conn ? conn->read_alerts : -1;
6900+}
6901+
6902+
6903+int tls_connection_get_write_alerts(void *tls_ctx,
6904+ struct tls_connection *conn)
6905+{
6906+ return conn ? conn->write_alerts : -1;
6907+}
6908+
6909+
6910+#ifdef TLS_MBEDTLS_SESSION_TICKETS
6911+int tls_connection_set_session_ticket_cb(
6912+ void *tls_ctx, struct tls_connection *conn,
6913+ tls_session_ticket_cb cb, void *ctx)
6914+{
6915+ if (!(conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)) {
6916+ /* (EAP-FAST and EAP-TEAP) */
6917+ conn->session_ticket_cb = cb;
6918+ conn->session_ticket_cb_ctx = ctx;
6919+ return 0;
6920+ }
6921+ return -1;
6922+}
6923+#endif
6924+
6925+
6926+int tls_get_library_version(char *buf, size_t buf_len)
6927+{
6928+ #ifndef MBEDTLS_VERSION_C
6929+ const char * const ver = "n/a";
6930+ #else
6931+ char ver[9];
6932+ mbedtls_version_get_string(ver);
6933+ #endif
6934+ return os_snprintf(buf, buf_len,
6935+ "mbed TLS build=" MBEDTLS_VERSION_STRING " run=%s", ver);
6936+}
6937+
6938+
6939+void tls_connection_set_success_data(struct tls_connection *conn,
6940+ struct wpabuf *data)
6941+{
6942+ wpabuf_free(conn->success_data);
6943+ conn->success_data = data;
6944+}
6945+
6946+
6947+void tls_connection_set_success_data_resumed(struct tls_connection *conn)
6948+{
6949+}
6950+
6951+
6952+const struct wpabuf *
6953+tls_connection_get_success_data(struct tls_connection *conn)
6954+{
6955+ return conn->success_data;
6956+}
6957+
6958+
6959+void tls_connection_remove_session(struct tls_connection *conn)
6960+{
6961+}
6962+
6963+
6964+#ifdef TLS_MBEDTLS_EAP_TEAP
6965+int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len)
6966+{
6967+ #if defined(MBEDTLS_SSL_RENEGOTIATION) /* XXX: renegotiation or resumption? */
6968+ /* data from TLS handshake Finished message */
6969+ size_t verify_len = conn->ssl.MBEDTLS_PRIVATE(verify_data_len);
6970+ char *verify_data = (conn->is_server ^ conn->resumed)
6971+ ? conn->ssl.MBEDTLS_PRIVATE(peer_verify_data)
6972+ : conn->ssl.MBEDTLS_PRIVATE(own_verify_data);
6973+ if (verify_len && verify_len <= max_len) {
6974+ os_memcpy(buf, verify_data, verify_len);
6975+ return (int)verify_len;
6976+ }
6977+ #endif
6978+ return -1;
6979+}
6980+#endif
6981+
6982+
6983+__attribute_noinline__
6984+static void tls_mbedtls_set_peer_subject(struct tls_connection *conn, const mbedtls_x509_crt *crt)
6985+{
6986+ if (conn->peer_subject)
6987+ return;
6988+ char buf[MBEDTLS_X509_MAX_DN_NAME_SIZE*2];
6989+ int buflen = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject);
6990+ if (buflen >= 0 && (conn->peer_subject = os_malloc((size_t)buflen+1)))
6991+ os_memcpy(conn->peer_subject, buf, (size_t)buflen+1);
6992+}
6993+
6994+
6995+#ifdef TLS_MBEDTLS_EAP_TEAP
6996+const char * tls_connection_get_peer_subject(struct tls_connection *conn)
6997+{
6998+ if (!conn)
6999+ return NULL;
7000+ if (!conn->peer_subject) { /*(if not set during cert verify)*/
7001+ const mbedtls_x509_crt *peer_cert =
7002+ mbedtls_ssl_get_peer_cert(&conn->ssl);
7003+ if (peer_cert)
7004+ tls_mbedtls_set_peer_subject(conn, peer_cert);
7005+ }
7006+ return conn->peer_subject;
7007+}
7008+#endif
7009+
7010+
7011+#ifdef TLS_MBEDTLS_EAP_TEAP
7012+bool tls_connection_get_own_cert_used(struct tls_connection *conn)
7013+{
7014+ /* XXX: availability of cert does not necessary mean that client
7015+ * received certificate request from server and then sent cert.
7016+ * ? step handshake in tls_connection_handshake() looking for
7017+ * MBEDTLS_SSL_CERTIFICATE_REQUEST ? */
7018+ const struct tls_conf * const tls_conf = conn->tls_conf;
7019+ return (tls_conf->has_client_cert && tls_conf->has_private_key);
7020+}
7021+#endif
7022+
7023+
7024+#if defined(CONFIG_FIPS)
7025+#define TLS_MBEDTLS_CONFIG_FIPS
7026+#endif
7027+
7028+#if defined(CONFIG_SHA256)
7029+#define TLS_MBEDTLS_TLS_PRF_SHA256
7030+#endif
7031+
7032+#if defined(CONFIG_SHA384)
7033+#define TLS_MBEDTLS_TLS_PRF_SHA384
7034+#endif
7035+
7036+
7037+#ifndef TLS_MBEDTLS_CONFIG_FIPS
7038+#if defined(CONFIG_MODULE_TESTS)
7039+/* unused with CONFIG_TLS=mbedtls except in crypto_module_tests.c */
7040+#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ \
7041+ && MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
7042+/* sha1-tlsprf.c */
7043+#include "sha1.h"
7044+int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label,
7045+ const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
7046+{
7047+ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1,
7048+ secret, secret_len, label,
7049+ seed, seed_len, out, outlen) ? -1 : 0;
7050+}
7051+#else
7052+#include "sha1-tlsprf.c" /* pull in hostap local implementation */
7053+#endif
7054+#endif
7055+#endif
7056+
7057+#ifdef TLS_MBEDTLS_TLS_PRF_SHA256
7058+/* sha256-tlsprf.c */
7059+#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
7060+#include "sha256.h"
7061+int tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label,
7062+ const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
7063+{
7064+ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA256,
7065+ secret, secret_len, label,
7066+ seed, seed_len, out, outlen) ? -1 : 0;
7067+}
7068+#else
7069+#include "sha256-tlsprf.c" /* pull in hostap local implementation */
7070+#endif
7071+#endif
7072+
7073+#ifdef TLS_MBEDTLS_TLS_PRF_SHA384
7074+/* sha384-tlsprf.c */
7075+#if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
7076+#include "sha384.h"
7077+int tls_prf_sha384(const u8 *secret, size_t secret_len, const char *label,
7078+ const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
7079+{
7080+ return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA384,
7081+ secret, secret_len, label,
7082+ seed, seed_len, out, outlen) ? -1 : 0;
7083+}
7084+#else
7085+#include "sha384-tlsprf.c" /* pull in hostap local implementation */
7086+#endif
7087+#endif
7088+
7089+
7090+#if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */
7091+#define mbedtls_x509_crt_has_ext_type(crt, ext_type) \
7092+ ((crt)->MBEDTLS_PRIVATE(ext_types) & (ext_type))
7093+#endif
7094+
7095+struct mlist { const char *p; size_t n; };
7096+
7097+
7098+static int
7099+tls_mbedtls_match_altsubject(mbedtls_x509_crt *crt, const char *match)
7100+{
7101+ /* RFE: this could be pre-parsed into structured data at config time */
7102+ struct mlist list[256]; /*(much larger than expected)*/
7103+ int nlist = 0;
7104+ if ( os_strncmp(match, "EMAIL:", 6) != 0
7105+ && os_strncmp(match, "DNS:", 4) != 0
7106+ && os_strncmp(match, "URI:", 4) != 0 ) {
7107+ wpa_printf(MSG_INFO, "MTLS: Invalid altSubjectName match '%s'", match);
7108+ return 0;
7109+ }
7110+ for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") {
7111+ do { } while ((tok = os_strchr(s, ';'))
7112+ && os_strncmp(tok+1, "EMAIL:", 6) != 0
7113+ && os_strncmp(tok+1, "DNS:", 4) != 0
7114+ && os_strncmp(tok+1, "URI:", 4) != 0);
7115+ list[nlist].p = s;
7116+ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s);
7117+ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) {
7118+ wpa_printf(MSG_INFO, "MTLS: excessive altSubjectName match '%s'",
7119+ match);
7120+ break; /* truncate huge list and continue */
7121+ }
7122+ }
7123+
7124+ if (!mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME))
7125+ return 0;
7126+
7127+ const mbedtls_x509_sequence *cur = &crt->subject_alt_names;
7128+ for (; cur != NULL; cur = cur->next) {
7129+ const unsigned char san_type = (unsigned char)cur->buf.tag
7130+ & MBEDTLS_ASN1_TAG_VALUE_MASK;
7131+ char t;
7132+ size_t step = 4;
7133+ switch (san_type) { /* "EMAIL:" or "DNS:" or "URI:" */
7134+ case MBEDTLS_X509_SAN_RFC822_NAME: step = 6; t = 'E'; break;
7135+ case MBEDTLS_X509_SAN_DNS_NAME: t = 'D'; break;
7136+ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: t = 'U'; break;
7137+ default: continue;
7138+ }
7139+
7140+ for (int i = 0; i < nlist; ++i) {
7141+ /* step over "EMAIL:" or "DNS:" or "URI:" in list[i].p */
7142+ /* Note: v is not '\0'-terminated, but is a known length vlen,
7143+ * so okay to pass to os_strncasecmp() even though not z-string */
7144+ if (cur->buf.len == list[i].n - step && t == *list[i].p
7145+ && 0 == os_strncasecmp((char *)cur->buf.p,
7146+ list[i].p+step, cur->buf.len)) {
7147+ return 1; /* match */
7148+ }
7149+ }
7150+ }
7151+ return 0; /* no match */
7152+}
7153+
7154+
7155+static int
7156+tls_mbedtls_match_suffix(const char *v, size_t vlen,
7157+ const struct mlist *list, int nlist, int full)
7158+{
7159+ /* Note: v is not '\0'-terminated, but is a known length vlen,
7160+ * so okay to pass to os_strncasecmp() even though not z-string */
7161+ for (int i = 0; i < nlist; ++i) {
7162+ size_t n = list[i].n;
7163+ if ((n == vlen || (n < vlen && v[vlen-n-1] == '.' && !full))
7164+ && 0 == os_strncasecmp(v+vlen-n, list[i].p, n))
7165+ return 1; /* match */
7166+ }
7167+ return 0; /* no match */
7168+}
7169+
7170+
7171+static int
7172+tls_mbedtls_match_suffixes(mbedtls_x509_crt *crt, const char *match, int full)
7173+{
7174+ /* RFE: this could be pre-parsed into structured data at config time */
7175+ struct mlist list[256]; /*(much larger than expected)*/
7176+ int nlist = 0;
7177+ for (const char *s = match, *tok; *s; s = tok ? tok+1 : "") {
7178+ tok = os_strchr(s, ';');
7179+ list[nlist].p = s;
7180+ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s);
7181+ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) {
7182+ wpa_printf(MSG_INFO, "MTLS: excessive suffix match '%s'", match);
7183+ break; /* truncate huge list and continue */
7184+ }
7185+ }
7186+
7187+ /* check subjectAltNames */
7188+ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME)) {
7189+ const mbedtls_x509_sequence *cur = &crt->subject_alt_names;
7190+ for (; cur != NULL; cur = cur->next) {
7191+ const unsigned char san_type = (unsigned char)cur->buf.tag
7192+ & MBEDTLS_ASN1_TAG_VALUE_MASK;
7193+ if (san_type == MBEDTLS_X509_SAN_DNS_NAME
7194+ && tls_mbedtls_match_suffix((char *)cur->buf.p,
7195+ cur->buf.len,
7196+ list, nlist, full)) {
7197+ return 1; /* match */
7198+ }
7199+ }
7200+ }
7201+
7202+ /* check subject CN */
7203+ const mbedtls_x509_name *name = &crt->subject;
7204+ for (; name != NULL; name = name->next) {
7205+ if (name->oid.p && MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0)
7206+ break;
7207+ }
7208+ if (name && tls_mbedtls_match_suffix((char *)name->val.p, name->val.len,
7209+ list, nlist, full)) {
7210+ return 1; /* match */
7211+ }
7212+
7213+ return 0; /* no match */
7214+}
7215+
7216+
7217+static int
7218+tls_mbedtls_match_dn_field(mbedtls_x509_crt *crt, const char *match)
7219+{
7220+ /* RFE: this could be pre-parsed into structured data at config time */
7221+ struct mlistoid { const char *p; size_t n;
7222+ const char *oid; size_t olen;
7223+ int prefix; };
7224+ struct mlistoid list[32]; /*(much larger than expected)*/
7225+ int nlist = 0;
7226+ for (const char *s = match, *tok, *e; *s; s = tok ? tok+1 : "") {
7227+ tok = os_strchr(s, '/');
7228+ list[nlist].oid = NULL;
7229+ list[nlist].olen = 0;
7230+ list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s);
7231+ e = memchr(s, '=', list[nlist].n);
7232+ if (e == NULL) {
7233+ if (list[nlist].n == 0)
7234+ continue; /* skip consecutive, repeated '/' */
7235+ if (list[nlist].n == 1 && *s == '*') {
7236+ /* special-case "*" to match any OID and value */
7237+ s = e = "=*";
7238+ list[nlist].n = 2;
7239+ list[nlist].oid = "";
7240+ }
7241+ else {
7242+ wpa_printf(MSG_INFO,
7243+ "MTLS: invalid check_cert_subject '%s' missing '='",
7244+ match);
7245+ return 0;
7246+ }
7247+ }
7248+ switch (e - s) {
7249+ case 1:
7250+ if (*s == 'C') {
7251+ list[nlist].oid = MBEDTLS_OID_AT_COUNTRY;
7252+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_COUNTRY)-1;
7253+ }
7254+ else if (*s == 'L') {
7255+ list[nlist].oid = MBEDTLS_OID_AT_LOCALITY;
7256+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_LOCALITY)-1;
7257+ }
7258+ else if (*s == 'O') {
7259+ list[nlist].oid = MBEDTLS_OID_AT_ORGANIZATION;
7260+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORGANIZATION)-1;
7261+ }
7262+ break;
7263+ case 2:
7264+ if (s[0] == 'C' && s[1] == 'N') {
7265+ list[nlist].oid = MBEDTLS_OID_AT_CN;
7266+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_CN)-1;
7267+ }
7268+ else if (s[0] == 'S' && s[1] == 'T') {
7269+ list[nlist].oid = MBEDTLS_OID_AT_STATE;
7270+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_STATE)-1;
7271+ }
7272+ else if (s[0] == 'O' && s[1] == 'U') {
7273+ list[nlist].oid = MBEDTLS_OID_AT_ORG_UNIT;
7274+ list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORG_UNIT)-1;
7275+ }
7276+ break;
7277+ case 12:
7278+ if (os_memcmp(s, "emailAddress", 12) == 0) {
7279+ list[nlist].oid = MBEDTLS_OID_PKCS9_EMAIL;
7280+ list[nlist].olen = sizeof(MBEDTLS_OID_PKCS9_EMAIL)-1;
7281+ }
7282+ break;
7283+ default:
7284+ break;
7285+ }
7286+ if (list[nlist].oid == NULL) {
7287+ wpa_printf(MSG_INFO,
7288+ "MTLS: Unknown field in check_cert_subject '%s'",
7289+ match);
7290+ return 0;
7291+ }
7292+ list[nlist].n -= (size_t)(++e - s);
7293+ list[nlist].p = e;
7294+ if (list[nlist].n && e[list[nlist].n-1] == '*') {
7295+ --list[nlist].n;
7296+ list[nlist].prefix = 1;
7297+ }
7298+ /*(could easily add support for suffix matches if value begins with '*',
7299+ * but suffix match is not currently supported by other TLS modules)*/
7300+
7301+ if (list[nlist].n && ++nlist == sizeof(list)/sizeof(*list)) {
7302+ wpa_printf(MSG_INFO,
7303+ "MTLS: excessive check_cert_subject match '%s'",
7304+ match);
7305+ break; /* truncate huge list and continue */
7306+ }
7307+ }
7308+
7309+ /* each component in match string must match cert Subject in order listed
7310+ * The behavior below preserves ordering but is slightly different than
7311+ * the grossly inefficient contortions implemented in tls_openssl.c */
7312+ const mbedtls_x509_name *name = &crt->subject;
7313+ for (int i = 0; i < nlist; ++i) {
7314+ int found = 0;
7315+ for (; name != NULL && !found; name = name->next) {
7316+ if (!name->oid.p)
7317+ continue;
7318+ /* special-case "*" to match any OID and value */
7319+ if (list[i].olen == 0) {
7320+ found = 1;
7321+ continue;
7322+ }
7323+ /* perform equalent of !MBEDTLS_OID_CMP() with oid ptr and len */
7324+ if (list[i].olen != name->oid.len
7325+ || os_memcmp(list[i].oid, name->oid.p, name->oid.len) != 0)
7326+ continue;
7327+ /* Note: v is not '\0'-terminated, but is a known length vlen,
7328+ * so okay to pass to os_strncasecmp() even though not z-string */
7329+ if ((list[i].prefix
7330+ ? list[i].n <= name->val.len /* prefix match */
7331+ : list[i].n == name->val.len) /* full match */
7332+ && 0 == os_strncasecmp((char *)name->val.p,
7333+ list[i].p, list[i].n)) {
7334+ found = 1;
7335+ continue;
7336+ }
7337+ }
7338+ if (!found)
7339+ return 0; /* no match */
7340+ }
7341+ return 1; /* match */
7342+}
7343+
7344+
7345+__attribute_cold__
7346+static void
7347+tls_mbedtls_verify_fail_event (mbedtls_x509_crt *crt, int depth,
7348+ const char *errmsg, enum tls_fail_reason reason)
7349+{
7350+ struct tls_config *init_conf = &tls_ctx_global.init_conf;
7351+ if (init_conf->event_cb == NULL)
7352+ return;
7353+
7354+ struct wpabuf *certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len);
7355+ char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2];
7356+ if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0)
7357+ subject[0] = '\0';
7358+ union tls_event_data ev;
7359+ os_memset(&ev, 0, sizeof(ev));
7360+ ev.cert_fail.reason = reason;
7361+ ev.cert_fail.depth = depth;
7362+ ev.cert_fail.subject = subject;
7363+ ev.cert_fail.reason_txt = errmsg;
7364+ ev.cert_fail.cert = certbuf;
7365+
7366+ init_conf->event_cb(init_conf->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
7367+
7368+ wpabuf_free(certbuf);
7369+}
7370+
7371+
7372+__attribute_noinline__
7373+static void
7374+tls_mbedtls_verify_cert_event (struct tls_connection *conn,
7375+ mbedtls_x509_crt *crt, int depth)
7376+{
7377+ struct tls_config *init_conf = &tls_ctx_global.init_conf;
7378+ if (init_conf->event_cb == NULL)
7379+ return;
7380+
7381+ struct wpabuf *certbuf = NULL;
7382+ union tls_event_data ev;
7383+ os_memset(&ev, 0, sizeof(ev));
7384+
7385+ #ifdef MBEDTLS_SHA256_C
7386+ u8 hash[SHA256_DIGEST_LENGTH];
7387+ const u8 *addr[] = { (u8 *)crt->raw.p };
7388+ if (sha256_vector(1, addr, &crt->raw.len, hash) == 0) {
7389+ ev.peer_cert.hash = hash;
7390+ ev.peer_cert.hash_len = sizeof(hash);
7391+ }
7392+ #endif
7393+ ev.peer_cert.depth = depth;
7394+ char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE*2];
7395+ if (depth == 0)
7396+ ev.peer_cert.subject = conn->peer_subject;
7397+ if (ev.peer_cert.subject == NULL) {
7398+ ev.peer_cert.subject = subject;
7399+ if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0)
7400+ subject[0] = '\0';
7401+ }
7402+
7403+ char serial_num[128+1];
7404+ ev.peer_cert.serial_num =
7405+ tls_mbedtls_peer_serial_num(crt, serial_num, sizeof(serial_num));
7406+
7407+ const mbedtls_x509_sequence *cur;
7408+
7409+ cur = NULL;
7410+ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME))
7411+ cur = &crt->subject_alt_names;
7412+ for (; cur != NULL; cur = cur->next) {
7413+ const unsigned char san_type = (unsigned char)cur->buf.tag
7414+ & MBEDTLS_ASN1_TAG_VALUE_MASK;
7415+ size_t prelen = 4;
7416+ const char *pre;
7417+ switch (san_type) {
7418+ case MBEDTLS_X509_SAN_RFC822_NAME: prelen = 6; pre = "EMAIL:";break;
7419+ case MBEDTLS_X509_SAN_DNS_NAME: pre = "DNS:"; break;
7420+ case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: pre = "URI:"; break;
7421+ default: continue;
7422+ }
7423+
7424+ char *pos = os_malloc(prelen + cur->buf.len + 1);
7425+ if (pos == NULL)
7426+ break;
7427+ ev.peer_cert.altsubject[ev.peer_cert.num_altsubject] = pos;
7428+ os_memcpy(pos, pre, prelen);
7429+ /* data should be properly backslash-escaped if needed,
7430+ * so code below does not re-escape, but does replace CTLs */
7431+ /*os_memcpy(pos+prelen, cur->buf.p, cur->buf.len);*/
7432+ /*pos[prelen+cur->buf.len] = '\0';*/
7433+ pos += prelen;
7434+ for (size_t i = 0; i < cur->buf.len; ++i) {
7435+ unsigned char c = cur->buf.p[i];
7436+ *pos++ = (c >= 32 && c != 127) ? c : '?';
7437+ }
7438+ *pos = '\0';
7439+
7440+ if (++ev.peer_cert.num_altsubject == TLS_MAX_ALT_SUBJECT)
7441+ break;
7442+ }
7443+
7444+ cur = NULL;
7445+ if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_CERTIFICATE_POLICIES))
7446+ cur = &crt->certificate_policies;
7447+ for (; cur != NULL; cur = cur->next) {
7448+ if (cur->buf.len != 11) /* len of OID_TOD_STRICT or OID_TOD_TOFU */
7449+ continue;
7450+ /* TOD-STRICT "1.3.6.1.4.1.40808.1.3.1" */
7451+ /* TOD-TOFU "1.3.6.1.4.1.40808.1.3.2" */
7452+ #define OID_TOD_STRICT "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x01"
7453+ #define OID_TOD_TOFU "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x02"
7454+ if (os_memcmp(cur->buf.p,
7455+ OID_TOD_STRICT, sizeof(OID_TOD_STRICT)-1) == 0) {
7456+ ev.peer_cert.tod = 1; /* TOD-STRICT */
7457+ break;
7458+ }
7459+ if (os_memcmp(cur->buf.p,
7460+ OID_TOD_TOFU, sizeof(OID_TOD_TOFU)-1) == 0) {
7461+ ev.peer_cert.tod = 2; /* TOD-TOFU */
7462+ break;
7463+ }
7464+ }
7465+
7466+ struct tls_conf *tls_conf = conn->tls_conf;
7467+ if (tls_conf->ca_cert_probe || (tls_conf->flags & TLS_CONN_EXT_CERT_CHECK)
7468+ || init_conf->cert_in_cb) {
7469+ certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len);
7470+ ev.peer_cert.cert = certbuf;
7471+ }
7472+
7473+ init_conf->event_cb(init_conf->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
7474+
7475+ wpabuf_free(certbuf);
7476+ char **altsubject;
7477+ *(const char ***)&altsubject = ev.peer_cert.altsubject;
7478+ for (size_t i = 0; i < ev.peer_cert.num_altsubject; ++i)
7479+ os_free(altsubject[i]);
7480+}
7481+
7482+
7483+static int
7484+tls_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
7485+{
7486+ /* XXX: N.B. verify code not carefully tested besides hwsim tests
7487+ *
7488+ * RFE: mbedtls_x509_crt_verify_info() and enhance log trace messages
7489+ * RFE: review and add support for additional TLS_CONN_* flags
7490+ * not handling OCSP (not available in mbedtls)
7491+ * ... */
7492+
7493+ struct tls_connection *conn = (struct tls_connection *)arg;
7494+ struct tls_conf *tls_conf = conn->tls_conf;
7495+ uint32_t flags_in = *flags;
7496+
7497+ if (depth > 8) { /*(depth 8 picked as arbitrary limit)*/
7498+ emsg(MSG_WARNING, "client cert chain too long");
7499+ *flags |= MBEDTLS_X509_BADCERT_OTHER; /* cert chain too long */
7500+ tls_mbedtls_verify_fail_event(crt, depth,
7501+ "client cert chain too long",
7502+ TLS_FAIL_BAD_CERTIFICATE);
7503+ }
7504+ else if (tls_conf->verify_depth0_only) {
7505+ if (depth > 0)
7506+ *flags = 0;
7507+ else {
7508+ #ifdef MBEDTLS_SHA256_C
7509+ u8 hash[SHA256_DIGEST_LENGTH];
7510+ const u8 *addr[] = { (u8 *)crt->raw.p };
7511+ if (sha256_vector(1, addr, &crt->raw.len, hash) < 0
7512+ || os_memcmp(tls_conf->ca_cert_hash, hash, sizeof(hash)) != 0) {
7513+ *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
7514+ tls_mbedtls_verify_fail_event(crt, depth,
7515+ "cert hash mismatch",
7516+ TLS_FAIL_UNTRUSTED);
7517+ }
7518+ else /* hash matches; ignore other issues *except* if revoked)*/
7519+ *flags &= MBEDTLS_X509_BADCERT_REVOKED;
7520+ #endif
7521+ }
7522+ }
7523+ else if (depth == 0) {
7524+ if (!conn->peer_subject)
7525+ tls_mbedtls_set_peer_subject(conn, crt);
7526+ /*(use same labels to tls_mbedtls_verify_fail_event() as used in
7527+ * other TLS modules so that hwsim tests find exact string match)*/
7528+ if (!conn->peer_subject) { /* error copying subject string */
7529+ *flags |= MBEDTLS_X509_BADCERT_OTHER;
7530+ tls_mbedtls_verify_fail_event(crt, depth,
7531+ "internal error",
7532+ TLS_FAIL_UNSPECIFIED);
7533+ }
7534+ /*(use os_strstr() for subject match as is done in tls_mbedtls.c
7535+ * to follow the same behavior, even though a suffix match would
7536+ * make more sense. Also, note that strstr match does not
7537+ * normalize whitespace (between components) for comparison)*/
7538+ else if (tls_conf->subject_match
7539+ && os_strstr(conn->peer_subject,
7540+ tls_conf->subject_match) == NULL) {
7541+ wpa_printf(MSG_WARNING,
7542+ "MTLS: Subject '%s' did not match with '%s'",
7543+ conn->peer_subject, tls_conf->subject_match);
7544+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
7545+ tls_mbedtls_verify_fail_event(crt, depth,
7546+ "Subject mismatch",
7547+ TLS_FAIL_SUBJECT_MISMATCH);
7548+ }
7549+ if (tls_conf->altsubject_match
7550+ && !tls_mbedtls_match_altsubject(crt, tls_conf->altsubject_match)) {
7551+ wpa_printf(MSG_WARNING,
7552+ "MTLS: altSubjectName match '%s' not found",
7553+ tls_conf->altsubject_match);
7554+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
7555+ tls_mbedtls_verify_fail_event(crt, depth,
7556+ "AltSubject mismatch",
7557+ TLS_FAIL_ALTSUBJECT_MISMATCH);
7558+ }
7559+ if (tls_conf->suffix_match
7560+ && !tls_mbedtls_match_suffixes(crt, tls_conf->suffix_match, 0)) {
7561+ wpa_printf(MSG_WARNING,
7562+ "MTLS: Domain suffix match '%s' not found",
7563+ tls_conf->suffix_match);
7564+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
7565+ tls_mbedtls_verify_fail_event(crt, depth,
7566+ "Domain suffix mismatch",
7567+ TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
7568+ }
7569+ if (tls_conf->domain_match
7570+ && !tls_mbedtls_match_suffixes(crt, tls_conf->domain_match, 1)) {
7571+ wpa_printf(MSG_WARNING,
7572+ "MTLS: Domain match '%s' not found",
7573+ tls_conf->domain_match);
7574+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
7575+ tls_mbedtls_verify_fail_event(crt, depth,
7576+ "Domain mismatch",
7577+ TLS_FAIL_DOMAIN_MISMATCH);
7578+ }
7579+ if (tls_conf->check_cert_subject
7580+ && !tls_mbedtls_match_dn_field(crt, tls_conf->check_cert_subject)) {
7581+ *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
7582+ tls_mbedtls_verify_fail_event(crt, depth,
7583+ "Distinguished Name",
7584+ TLS_FAIL_DN_MISMATCH);
7585+ }
7586+ if (tls_conf->flags & TLS_CONN_SUITEB) {
7587+ /* check RSA modulus size (public key bitlen) */
7588+ const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&crt->pk);
7589+ if ((pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS)
7590+ && mbedtls_pk_get_bitlen(&crt->pk) < 3072) {
7591+ /* hwsim suite_b RSA tests expect 3072
7592+ * suite_b_192_rsa_ecdhe_radius_rsa2048_client
7593+ * suite_b_192_rsa_dhe_radius_rsa2048_client */
7594+ *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
7595+ tls_mbedtls_verify_fail_event(crt, depth,
7596+ "Insufficient RSA modulus size",
7597+ TLS_FAIL_INSUFFICIENT_KEY_LEN);
7598+ }
7599+ }
7600+ if (tls_conf->check_crl && tls_conf->crl == NULL) {
7601+ /* see tests/hwsim test_ap_eap.py ap_wpa2_eap_tls_check_crl */
7602+ emsg(MSG_WARNING, "check_crl set but no CRL loaded; reject all?");
7603+ *flags |= MBEDTLS_X509_BADCERT_OTHER;
7604+ tls_mbedtls_verify_fail_event(crt, depth,
7605+ "check_crl set but no CRL loaded; "
7606+ "reject all?",
7607+ TLS_FAIL_BAD_CERTIFICATE);
7608+ }
7609+ }
7610+ else {
7611+ if (tls_conf->check_crl != 2) /* 2 == verify CRLs for all certs */
7612+ *flags &= ~MBEDTLS_X509_BADCERT_REVOKED;
7613+ }
7614+
7615+ if (!tls_conf->check_crl_strict) {
7616+ *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED;
7617+ *flags &= ~MBEDTLS_X509_BADCRL_FUTURE;
7618+ }
7619+
7620+ if (tls_conf->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
7621+ *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED;
7622+ *flags &= ~MBEDTLS_X509_BADCERT_FUTURE;
7623+ }
7624+
7625+ tls_mbedtls_verify_cert_event(conn, crt, depth);
7626+
7627+ if (*flags) {
7628+ if (*flags & (MBEDTLS_X509_BADCERT_NOT_TRUSTED
7629+ |MBEDTLS_X509_BADCERT_CN_MISMATCH
7630+ |MBEDTLS_X509_BADCERT_REVOKED)) {
7631+ emsg(MSG_WARNING, "client cert not trusted");
7632+ }
7633+ /* report event if flags set but no additional flags set above */
7634+ /* (could translate flags to more detailed TLS_FAIL_* if needed) */
7635+ if (!(*flags & ~flags_in)) {
7636+ enum tls_fail_reason reason = TLS_FAIL_UNSPECIFIED;
7637+ const char *errmsg = "cert verify fail unspecified";
7638+ if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
7639+ reason = TLS_FAIL_UNTRUSTED;
7640+ errmsg = "certificate not trusted";
7641+ }
7642+ if (*flags & MBEDTLS_X509_BADCERT_REVOKED) {
7643+ reason = TLS_FAIL_REVOKED;
7644+ errmsg = "certificate has been revoked";
7645+ }
7646+ if (*flags & MBEDTLS_X509_BADCERT_FUTURE) {
7647+ reason = TLS_FAIL_NOT_YET_VALID;
7648+ errmsg = "certificate not yet valid";
7649+ }
7650+ if (*flags & MBEDTLS_X509_BADCERT_EXPIRED) {
7651+ reason = TLS_FAIL_EXPIRED;
7652+ errmsg = "certificate has expired";
7653+ }
7654+ if (*flags & MBEDTLS_X509_BADCERT_BAD_MD) {
7655+ reason = TLS_FAIL_BAD_CERTIFICATE;
7656+ errmsg = "certificate uses insecure algorithm";
7657+ }
7658+ tls_mbedtls_verify_fail_event(crt, depth, errmsg, reason);
7659+ }
7660+ #if 0
7661+ /* ??? send (again) cert events for all certs in chain ???
7662+ * (should already have been called for greater depths) */
7663+ /* tls_openssl.c:tls_verify_cb() sends cert events for all certs
7664+ * in chain if certificate validation fails, but sends all events
7665+ * with depth set to 0 (might be a bug) */
7666+ if (depth > 0) {
7667+ int pdepth = depth + 1;
7668+ for (mbedtls_x509_crt *pcrt; (pcrt = crt->next); ++pdepth) {
7669+ tls_mbedtls_verify_cert_event(conn, pcrt, pdepth);
7670+ }
7671+ }
7672+ #endif
7673+ /*(do not preserve subject if verification failed but was optional)*/
7674+ if (depth == 0 && conn->peer_subject) {
7675+ os_free(conn->peer_subject);
7676+ conn->peer_subject = NULL;
7677+ }
7678+ }
7679+ else if (depth == 0) {
7680+ struct tls_config *init_conf = &tls_ctx_global.init_conf;
7681+ if (tls_conf->ca_cert_probe) {
7682+ /* reject server certificate on probe-only run */
7683+ *flags |= MBEDTLS_X509_BADCERT_OTHER;
7684+ tls_mbedtls_verify_fail_event(crt, depth,
7685+ "server chain probe",
7686+ TLS_FAIL_SERVER_CHAIN_PROBE);
7687+ }
7688+ else if (init_conf->event_cb) {
7689+ /* ??? send event as soon as depth == 0 is verified ???
7690+ * What about rest of chain?
7691+ * Follows tls_mbedtls.c behavior: */
7692+ init_conf->event_cb(init_conf->cb_ctx,
7693+ TLS_CERT_CHAIN_SUCCESS, NULL);
7694+ }
7695+ }
7696+
7697+ return 0;
7698+}
7699--- /dev/null
7700+++ b/tests/build/build-wpa_supplicant-mbedtls.config
7701@@ -0,0 +1,24 @@
7702+CONFIG_TLS=mbedtls
7703+
7704+CONFIG_WPS=y
7705+CONFIG_EAP_TLS=y
7706+CONFIG_EAP_MSCHAPV2=y
7707+
7708+CONFIG_EAP_PSK=y
7709+CONFIG_EAP_GPSK=y
7710+CONFIG_EAP_AKA=y
7711+CONFIG_EAP_SIM=y
7712+CONFIG_EAP_SAKE=y
7713+CONFIG_EAP_PAX=y
7714+CONFIG_EAP_FAST=y
7715+CONFIG_EAP_IKEV2=y
7716+
7717+CONFIG_SAE=y
7718+CONFIG_FILS=y
7719+CONFIG_FILS_SK_PFS=y
7720+CONFIG_OWE=y
7721+CONFIG_DPP=y
7722+CONFIG_SUITEB=y
7723+CONFIG_SUITEB192=y
7724+
7725+CFLAGS += -Werror
7726--- a/tests/hwsim/example-hostapd.config
7727+++ b/tests/hwsim/example-hostapd.config
7728@@ -4,6 +4,7 @@ CONFIG_DRIVER_NONE=y
7729 CONFIG_DRIVER_NL80211=y
7730 CONFIG_RSN_PREAUTH=y
7731
7732+#CONFIG_TLS=mbedtls
7733 #CONFIG_TLS=internal
7734 #CONFIG_INTERNAL_LIBTOMMATH=y
7735 #CONFIG_INTERNAL_LIBTOMMATH_FAST=y
7736@@ -39,6 +40,9 @@ endif
7737 ifeq ($(CONFIG_TLS), wolfssl)
7738 CONFIG_EAP_PWD=y
7739 endif
7740+ifeq ($(CONFIG_TLS), mbedtls)
7741+CONFIG_EAP_PWD=y
7742+endif
7743 CONFIG_EAP_EKE=y
7744 CONFIG_PKCS12=y
7745 CONFIG_RADIUS_SERVER=y
7746--- a/tests/hwsim/example-wpa_supplicant.config
7747+++ b/tests/hwsim/example-wpa_supplicant.config
7748@@ -2,6 +2,7 @@
7749
7750 CONFIG_TLS=openssl
7751 #CONFIG_TLS=wolfssl
7752+#CONFIG_TLS=mbedtls
7753 #CONFIG_TLS=internal
7754 #CONFIG_INTERNAL_LIBTOMMATH=y
7755 #CONFIG_INTERNAL_LIBTOMMATH_FAST=y
7756@@ -41,6 +42,9 @@ endif
7757 ifeq ($(CONFIG_TLS), wolfssl)
7758 CONFIG_EAP_PWD=y
7759 endif
7760+ifeq ($(CONFIG_TLS), mbedtls)
7761+CONFIG_EAP_PWD=y
7762+endif
7763
7764 CONFIG_USIM_SIMULATOR=y
7765 CONFIG_SIM_SIMULATOR=y
7766--- a/wpa_supplicant/Makefile
7767+++ b/wpa_supplicant/Makefile
7768@@ -1149,6 +1149,29 @@ endif
7769 CFLAGS += -DTLS_DEFAULT_CIPHERS=\"$(CONFIG_TLS_DEFAULT_CIPHERS)\"
7770 endif
7771
7772+ifeq ($(CONFIG_TLS), mbedtls)
7773+ifndef CONFIG_CRYPTO
7774+CONFIG_CRYPTO=mbedtls
7775+endif
7776+ifdef TLS_FUNCS
7777+OBJS += ../src/crypto/tls_mbedtls.o
7778+LIBS += -lmbedtls -lmbedx509
7779+endif
7780+OBJS += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
7781+OBJS_p += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
7782+OBJS_priv += ../src/crypto/crypto_$(CONFIG_CRYPTO).o
7783+ifdef NEED_FIPS186_2_PRF
7784+OBJS += ../src/crypto/fips_prf_internal.o
7785+SHA1OBJS += ../src/crypto/sha1-internal.o
7786+endif
7787+ifeq ($(CONFIG_CRYPTO), mbedtls)
7788+LIBS += -lmbedcrypto
7789+LIBS_p += -lmbedcrypto
7790+# XXX: create a config option?
7791+CFLAGS += -DCRYPTO_RSA_OAEP_SHA256
7792+endif
7793+endif
7794+
7795 ifeq ($(CONFIG_TLS), gnutls)
7796 ifndef CONFIG_CRYPTO
7797 # default to libgcrypt
7798@@ -1341,9 +1364,11 @@ endif
7799
7800 ifneq ($(CONFIG_TLS), openssl)
7801 ifneq ($(CONFIG_TLS), wolfssl)
7802+ifneq ($(CONFIG_TLS), mbedtls)
7803 NEED_INTERNAL_AES_WRAP=y
7804 endif
7805 endif
7806+endif
7807 ifdef CONFIG_OPENSSL_INTERNAL_AES_WRAP
7808 # Seems to be needed at least with BoringSSL
7809 NEED_INTERNAL_AES_WRAP=y
7810@@ -1357,9 +1382,11 @@ endif
7811
7812 ifdef NEED_INTERNAL_AES_WRAP
7813 ifneq ($(CONFIG_TLS), linux)
7814+ifneq ($(CONFIG_TLS), mbedtls)
7815 AESOBJS += ../src/crypto/aes-unwrap.o
7816 endif
7817 endif
7818+endif
7819 ifdef NEED_AES_EAX
7820 AESOBJS += ../src/crypto/aes-eax.o
7821 NEED_AES_CTR=y
7822@@ -1369,35 +1396,45 @@ AESOBJS += ../src/crypto/aes-siv.o
7823 NEED_AES_CTR=y
7824 endif
7825 ifdef NEED_AES_CTR
7826+ifneq ($(CONFIG_TLS), mbedtls)
7827 AESOBJS += ../src/crypto/aes-ctr.o
7828 endif
7829+endif
7830 ifdef NEED_AES_ENCBLOCK
7831+ifneq ($(CONFIG_TLS), mbedtls)
7832 AESOBJS += ../src/crypto/aes-encblock.o
7833 endif
7834+endif
7835 NEED_AES_ENC=y
7836 ifneq ($(CONFIG_TLS), openssl)
7837 ifneq ($(CONFIG_TLS), linux)
7838 ifneq ($(CONFIG_TLS), wolfssl)
7839+ifneq ($(CONFIG_TLS), mbedtls)
7840 AESOBJS += ../src/crypto/aes-omac1.o
7841 endif
7842 endif
7843 endif
7844+endif
7845 ifdef NEED_AES_WRAP
7846 NEED_AES_ENC=y
7847 ifdef NEED_INTERNAL_AES_WRAP
7848+ifneq ($(CONFIG_TLS), mbedtls)
7849 AESOBJS += ../src/crypto/aes-wrap.o
7850 endif
7851 endif
7852+endif
7853 ifdef NEED_AES_CBC
7854 NEED_AES_ENC=y
7855 ifneq ($(CONFIG_TLS), openssl)
7856 ifneq ($(CONFIG_TLS), linux)
7857 ifneq ($(CONFIG_TLS), wolfssl)
7858+ifneq ($(CONFIG_TLS), mbedtls)
7859 AESOBJS += ../src/crypto/aes-cbc.o
7860 endif
7861 endif
7862 endif
7863 endif
7864+endif
7865 ifdef NEED_AES_ENC
7866 ifdef CONFIG_INTERNAL_AES
7867 AESOBJS += ../src/crypto/aes-internal-enc.o
7868@@ -1412,12 +1449,16 @@ ifneq ($(CONFIG_TLS), openssl)
7869 ifneq ($(CONFIG_TLS), linux)
7870 ifneq ($(CONFIG_TLS), gnutls)
7871 ifneq ($(CONFIG_TLS), wolfssl)
7872+ifneq ($(CONFIG_TLS), mbedtls)
7873 SHA1OBJS += ../src/crypto/sha1.o
7874 endif
7875 endif
7876 endif
7877 endif
7878+endif
7879+ifneq ($(CONFIG_TLS), mbedtls)
7880 SHA1OBJS += ../src/crypto/sha1-prf.o
7881+endif
7882 ifdef CONFIG_INTERNAL_SHA1
7883 SHA1OBJS += ../src/crypto/sha1-internal.o
7884 ifdef NEED_FIPS186_2_PRF
7885@@ -1429,29 +1470,37 @@ CFLAGS += -DCONFIG_NO_PBKDF2
7886 else
7887 ifneq ($(CONFIG_TLS), openssl)
7888 ifneq ($(CONFIG_TLS), wolfssl)
7889+ifneq ($(CONFIG_TLS), mbedtls)
7890 SHA1OBJS += ../src/crypto/sha1-pbkdf2.o
7891 endif
7892 endif
7893 endif
7894+endif
7895 ifdef NEED_T_PRF
7896+ifneq ($(CONFIG_TLS), mbedtls)
7897 SHA1OBJS += ../src/crypto/sha1-tprf.o
7898 endif
7899+endif
7900 ifdef NEED_TLS_PRF
7901+ifneq ($(CONFIG_TLS), mbedtls)
7902 SHA1OBJS += ../src/crypto/sha1-tlsprf.o
7903 endif
7904 endif
7905+endif
7906
7907 ifndef CONFIG_FIPS
7908 ifneq ($(CONFIG_TLS), openssl)
7909 ifneq ($(CONFIG_TLS), linux)
7910 ifneq ($(CONFIG_TLS), gnutls)
7911 ifneq ($(CONFIG_TLS), wolfssl)
7912+ifneq ($(CONFIG_TLS), mbedtls)
7913 MD5OBJS += ../src/crypto/md5.o
7914 endif
7915 endif
7916 endif
7917 endif
7918 endif
7919+endif
7920 ifdef NEED_MD5
7921 ifdef CONFIG_INTERNAL_MD5
7922 MD5OBJS += ../src/crypto/md5-internal.o
7923@@ -1506,12 +1555,17 @@ ifneq ($(CONFIG_TLS), openssl)
7924 ifneq ($(CONFIG_TLS), linux)
7925 ifneq ($(CONFIG_TLS), gnutls)
7926 ifneq ($(CONFIG_TLS), wolfssl)
7927+ifneq ($(CONFIG_TLS), mbedtls)
7928 SHA256OBJS += ../src/crypto/sha256.o
7929 endif
7930 endif
7931 endif
7932 endif
7933+endif
7934+
7935+ifneq ($(CONFIG_TLS), mbedtls)
7936 SHA256OBJS += ../src/crypto/sha256-prf.o
7937+endif
7938 ifdef CONFIG_INTERNAL_SHA256
7939 SHA256OBJS += ../src/crypto/sha256-internal.o
7940 endif
7941@@ -1524,50 +1578,68 @@ CFLAGS += -DCONFIG_INTERNAL_SHA512
7942 SHA256OBJS += ../src/crypto/sha512-internal.o
7943 endif
7944 ifdef NEED_TLS_PRF_SHA256
7945+ifneq ($(CONFIG_TLS), mbedtls)
7946 SHA256OBJS += ../src/crypto/sha256-tlsprf.o
7947 endif
7948+endif
7949 ifdef NEED_TLS_PRF_SHA384
7950+ifneq ($(CONFIG_TLS), mbedtls)
7951 SHA256OBJS += ../src/crypto/sha384-tlsprf.o
7952 endif
7953+endif
7954 ifdef NEED_HMAC_SHA256_KDF
7955 CFLAGS += -DCONFIG_HMAC_SHA256_KDF
7956+ifneq ($(CONFIG_TLS), mbedtls)
7957 OBJS += ../src/crypto/sha256-kdf.o
7958 endif
7959+endif
7960 ifdef NEED_HMAC_SHA384_KDF
7961 CFLAGS += -DCONFIG_HMAC_SHA384_KDF
7962+ifneq ($(CONFIG_TLS), mbedtls)
7963 OBJS += ../src/crypto/sha384-kdf.o
7964 endif
7965+endif
7966 ifdef NEED_HMAC_SHA512_KDF
7967 CFLAGS += -DCONFIG_HMAC_SHA512_KDF
7968+ifneq ($(CONFIG_TLS), mbedtls)
7969 OBJS += ../src/crypto/sha512-kdf.o
7970 endif
7971+endif
7972 OBJS += $(SHA256OBJS)
7973 ifdef NEED_SHA384
7974 ifneq ($(CONFIG_TLS), openssl)
7975 ifneq ($(CONFIG_TLS), linux)
7976 ifneq ($(CONFIG_TLS), gnutls)
7977 ifneq ($(CONFIG_TLS), wolfssl)
7978+ifneq ($(CONFIG_TLS), mbedtls)
7979 OBJS += ../src/crypto/sha384.o
7980 endif
7981 endif
7982 endif
7983 endif
7984+endif
7985 CFLAGS += -DCONFIG_SHA384
7986+ifneq ($(CONFIG_TLS), mbedtls)
7987 OBJS += ../src/crypto/sha384-prf.o
7988 endif
7989+endif
7990 ifdef NEED_SHA512
7991 ifneq ($(CONFIG_TLS), openssl)
7992 ifneq ($(CONFIG_TLS), linux)
7993 ifneq ($(CONFIG_TLS), gnutls)
7994 ifneq ($(CONFIG_TLS), wolfssl)
7995+ifneq ($(CONFIG_TLS), mbedtls)
7996 OBJS += ../src/crypto/sha512.o
7997 endif
7998 endif
7999 endif
8000 endif
8001+endif
8002 CFLAGS += -DCONFIG_SHA512
8003+ifneq ($(CONFIG_TLS), mbedtls)
8004 OBJS += ../src/crypto/sha512-prf.o
8005 endif
8006+endif
8007
8008 ifdef NEED_ASN1
8009 OBJS += ../src/tls/asn1.o
8010@@ -1742,10 +1814,12 @@ ifdef CONFIG_FIPS
8011 CFLAGS += -DCONFIG_FIPS
8012 ifneq ($(CONFIG_TLS), openssl)
8013 ifneq ($(CONFIG_TLS), wolfssl)
8014+ifneq ($(CONFIG_TLS), mbedtls)
8015 $(error CONFIG_FIPS=y requires CONFIG_TLS=openssl)
8016 endif
8017 endif
8018 endif
8019+endif
8020
8021 OBJS += $(SHA1OBJS) $(DESOBJS)
8022
8023--- a/wpa_supplicant/defconfig
8024+++ b/wpa_supplicant/defconfig
8025@@ -10,8 +10,8 @@
8026 # to override previous values of the variables.
8027
8028
8029-# Uncomment following two lines and fix the paths if you have installed OpenSSL
8030-# or GnuTLS in non-default location
8031+# Uncomment following two lines and fix the paths if you have installed TLS
8032+# libraries in a non-default location
8033 #CFLAGS += -I/usr/local/openssl/include
8034 #LIBS += -L/usr/local/openssl/lib
8035
8036@@ -20,6 +20,7 @@
8037 # used to fix build issues on such systems (krb5.h not found).
8038 #CFLAGS += -I/usr/include/kerberos
8039
8040+
8041 # Driver interface for generic Linux wireless extensions
8042 # Note: WEXT is deprecated in the current Linux kernel version and no new
8043 # functionality is added to it. nl80211-based interface is the new
8044@@ -326,6 +327,7 @@ CONFIG_BACKEND=file
8045 # openssl = OpenSSL (default)
8046 # gnutls = GnuTLS
8047 # internal = Internal TLSv1 implementation (experimental)
8048+# mbedtls = mbed TLS
8049 # linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
8050 # none = Empty template
8051 #CONFIG_TLS=openssl