1 /*
2 * crypto wrapper functions for mbed TLS
3 *
4 * SPDX-FileCopyrightText: 2022 Glenn Strauss <gstrauss@gluelogic.com>
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "utils/includes.h"
9 #include "utils/common.h"
10
11 #ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE
12 #include <mbedtls/version.h>
13 #include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */
14 #include <mbedtls/asn1.h>
15 #include <mbedtls/asn1write.h>
16 #include <mbedtls/aes.h>
17 #include <mbedtls/md.h>
18 #include <mbedtls/md5.h>
19 #include <mbedtls/sha1.h>
20 #include <mbedtls/sha256.h>
21 #include <mbedtls/sha512.h>
22
23 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
24 #include "supp_psa_api.h"
25 #endif
26
27 #ifndef MBEDTLS_PRIVATE
28 #define MBEDTLS_PRIVATE(x) x
29 #endif
30
31 #define ENTROPY_MIN_PLATFORM 32
32
33 /* hostapd/wpa_supplicant provides forced_memzero(),
34 * but prefer mbedtls_platform_zeroize() */
35 #define forced_memzero(ptr, sz) mbedtls_platform_zeroize(ptr, sz)
36
37 #define IANA_SECP256R1 19
38 #define IANA_SECP384R1 20
39 #define IANA_SECP521R1 21
40
41 #ifdef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT
42 #define ACCESS_ECDH(S, var) S->MBEDTLS_PRIVATE(var)
43 #else
44 #define ACCESS_ECDH(S, var) S->MBEDTLS_PRIVATE(ctx).MBEDTLS_PRIVATE(mbed_ecdh).MBEDTLS_PRIVATE(var)
45 #endif
46
47 #ifndef __has_attribute
48 #define __has_attribute(x) 0
49 #endif
50
51 #ifndef __GNUC_PREREQ
52 #define __GNUC_PREREQ(maj, min) 0
53 #endif
54
55 #ifndef __attribute_cold__
56 #if __has_attribute(cold) || __GNUC_PREREQ(4, 3)
57 #define __attribute_cold__ __attribute__((__cold__))
58 #else
59 #define __attribute_cold__
60 #endif
61 #endif
62
63 #ifndef __attribute_noinline__
64 #if __has_attribute(noinline) || __GNUC_PREREQ(3, 1)
65 #define __attribute_noinline__ __attribute__((__noinline__))
66 #else
67 #define __attribute_noinline__
68 #endif
69 #endif
70
71 #include "crypto.h"
72 #include "aes_wrap.h"
73 #include "aes.h"
74 #include "md5.h"
75 #include "sha1.h"
76 #include "sha256.h"
77 #include "sha384.h"
78 #include "sha512.h"
79
80 /*
81 * selective code inclusion based on preprocessor defines
82 *
83 * future: additional code could be wrapped with preprocessor checks if
84 * wpa_supplicant/Makefile and hostap/Makefile were more consistent with
85 * setting preprocessor defines for named groups of functionality
86 */
87
88 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) || defined(EAP_TEAP) || \
89 defined(EAP_TEAP_DYNAMIC) || defined(EAP_SERVER_FAST)
90 #define CRYPTO_MBEDTLS_SHA1_T_PRF
91 #endif
92
93 #if !defined(CONFIG_NO_PBKDF2)
94 #define CRYPTO_MBEDTLS_PBKDF2_SHA1
95 #endif /* pbkdf2_sha1() */
96
97 #if defined(EAP_IKEV2) || defined(EAP_IKEV2_DYNAMIC) || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */
98 #define CRYPTO_MBEDTLS_CRYPTO_CIPHER
99 #endif /* crypto_cipher_*() */
100
101 #if defined(EAP_PWD) || defined(EAP_SERVER_PWD) /* CONFIG_EAP_PWD=y */ \
102 || defined(CONFIG_SAE) /* CONFIG_SAE=y */
103 #define CRYPTO_MBEDTLS_CRYPTO_BIGNUM
104 #endif /* crypto_bignum_*() */
105
106 #if defined(EAP_PWD) /* CONFIG_EAP_PWD=y */ \
107 || defined(EAP_EKE) /* CONFIG_EAP_EKE=y */ \
108 || defined(EAP_EKE_DYNAMIC) /* CONFIG_EAP_EKE=y */ \
109 || defined(EAP_SERVER_EKE) /* CONFIG_EAP_EKE=y */ \
110 || defined(EAP_IKEV2) /* CONFIG_EAP_IKEV2y */ \
111 || defined(EAP_IKEV2_DYNAMIC) /* CONFIG_EAP_IKEV2=y */ \
112 || defined(EAP_SERVER_IKEV2) /* CONFIG_EAP_IKEV2=y */ \
113 || defined(CONFIG_SAE) /* CONFIG_SAE=y */ \
114 || defined(CONFIG_WPS) /* CONFIG_WPS=y */
115 #define CRYPTO_MBEDTLS_CRYPTO_DH
116 #if defined(CONFIG_WPS_NFC)
117 #define CRYPTO_MBEDTLS_DH5_INIT_FIXED
118 #endif /* dh5_init_fixed() */
119 #endif /* crypto_dh_*() */
120
121 #if defined(MBEDTLS_ECDH_C) || defined(CONFIG_PSA_WANT_ALG_ECDH)
122 #define CRYPTO_MBEDTLS_CRYPTO_ECDH
123 #endif /* crypto_ecdh_*() */
124
125 #define CRYPTO_MBEDTLS_CRYPTO_BIGNUM
126
127 #if defined(CONFIG_DPP) || defined(CONFIG_SAE_PK) || defined(EAP_PWD) \
128 || defined(EAP_SERVER_PWD) || defined(CONFIG_SAE)
129 #define CRYPTO_MBEDTLS_CRYPTO_EC
130 #endif
131
132 #if defined(CONFIG_DPP) /* CONFIG_DPP=y */
133 #define CRYPTO_MBEDTLS_CRYPTO_EC_DPP /* extra for DPP */
134 #define CRYPTO_MBEDTLS_CRYPTO_CSR
135 #endif /* crypto_csr_*() */
136
137 #if defined(CONFIG_DPP2) /* CONFIG_DPP2=y */
138 #define CRYPTO_MBEDTLS_CRYPTO_PKCS7
139 #endif /* crypto_pkcs7_*() */
140
141 #if defined(EAP_SIM) || defined(EAP_SIM_DYNAMIC) || defined(EAP_SERVER_SIM) || defined(EAP_AKA) || \
142 defined(EAP_AKA_DYNAMIC) || defined(EAP_SERVER_AKA) || defined(CONFIG_AP) || defined(HOSTAPD)
143 /* CONFIG_EAP_SIM=y CONFIG_EAP_AKA=y CONFIG_AP=y HOSTAPD */
144 #if defined(CRYPTO_RSA_OAEP_SHA256)
145 #define CRYPTO_MBEDTLS_CRYPTO_RSA
146 #endif
147
148 #endif /* crypto_rsa_*() */
149
150
151
152 #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
153 #include <mbedtls/psa_util.h>
154 /* Setting ctr_drbg_init_state to 1 to allow unload_crypto to run */
155 static int ctr_drbg_init_state = 1;
156 int (*hostap_rng_fn)(void*, unsigned char*, size_t) = mbedtls_psa_get_random;
157 #else
158 #include <mbedtls/entropy.h>
159 #include <mbedtls/ctr_drbg.h>
160 static int ctr_drbg_init_state;
161 static mbedtls_ctr_drbg_context ctr_drbg;
162 static mbedtls_entropy_context entropy;
163 int(*hostap_rng_fn)(void*, unsigned char*, size_t) = mbedtls_ctr_drbg_random;
164 #endif
165
166 #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM
167 #include <mbedtls/bignum.h>
168 static mbedtls_mpi mpi_sw_A;
169 #endif
170
171 #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
wm_wrap_entropy_poll(void * data,unsigned char * output,size_t len,size_t * olen)172 static int wm_wrap_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen)
173 {
174 ((void)data);
175 os_get_random(output, len);
176 *olen = len;
177 return 0;
178 }
179
ctr_drbg_init(void)180 __attribute_cold__ __attribute_noinline__ static mbedtls_ctr_drbg_context *ctr_drbg_init(void)
181 {
182 const unsigned char *custom_name = (const unsigned char *)"WPA_SUPPLICANT/HOSTAPD";
183 size_t custom_name_len = os_strlen((const char *)custom_name);
184
185 mbedtls_ctr_drbg_init(&ctr_drbg);
186 mbedtls_entropy_init(&entropy);
187
188 mbedtls_entropy_add_source(&entropy, wm_wrap_entropy_poll, NULL, ENTROPY_MIN_PLATFORM,
189 MBEDTLS_ENTROPY_SOURCE_STRONG);
190
191 if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, custom_name, custom_name_len))
192 {
193 wpa_printf(MSG_ERROR, "Init of random number generator failed");
194 /* XXX: abort? */
195 }
196 else
197 ctr_drbg_init_state = 1;
198
199 return &ctr_drbg;
200 }
201 #endif
202
crypto_unload(void)203 __attribute_cold__ void crypto_unload(void)
204 {
205 if (ctr_drbg_init_state)
206 {
207 #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
208 mbedtls_ctr_drbg_free(&ctr_drbg);
209 mbedtls_entropy_free(&entropy);
210 #endif
211 #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM
212 mbedtls_mpi_free(&mpi_sw_A);
213 #endif
214 ctr_drbg_init_state = 0;
215 }
216 }
217
218 #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
219 /* init ctr_drbg on first use
220 * crypto_global_init() and crypto_global_deinit() are not available here
221 * (available only when CONFIG_TLS=internal, which is not CONFIG_TLS=mbedtls) */
222 mbedtls_ctr_drbg_context *crypto_mbedtls_ctr_drbg(void); /*(not in header)*/
crypto_mbedtls_ctr_drbg(void)223 inline mbedtls_ctr_drbg_context *crypto_mbedtls_ctr_drbg(void)
224 {
225 return ctr_drbg_init_state ? &ctr_drbg : ctr_drbg_init();
226 }
227 #endif
228
hostap_rng_ctx(void)229 void *hostap_rng_ctx(void)
230 {
231 #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
232 return MBEDTLS_PSA_RANDOM_STATE;
233 #else
234 return (mbedtls_ctr_drbg_context *) crypto_mbedtls_ctr_drbg();
235 #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
236 }
237
238 /* tradeoff: slightly smaller code size here at cost of slight increase
239 * in instructions and function calls at runtime versus the expanded
240 * per-message-digest code that follows in #else (~0.5 kib .text larger) */
md_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,mbedtls_md_type_t md_type)241 __attribute_noinline__ static int md_vector(
242 size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac, mbedtls_md_type_t md_type)
243 {
244 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
245 return md_vector_psa(num_elem, addr, len, mac, md_type);
246 #else
247 if (TEST_FAIL())
248 return -1;
249
250 mbedtls_md_context_t ctx;
251 mbedtls_md_init(&ctx);
252 if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0) != 0)
253 {
254 mbedtls_md_free(&ctx);
255 return -1;
256 }
257 mbedtls_md_starts(&ctx);
258 for (size_t i = 0; i < num_elem; ++i)
259 mbedtls_md_update(&ctx, addr[i], len[i]);
260 mbedtls_md_finish(&ctx, mac);
261 mbedtls_md_free(&ctx);
262 return 0;
263 #endif
264 }
265
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)266 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
267 {
268 return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA512);
269 }
270
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)271 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
272 {
273 return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA384);
274 }
275
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)276 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
277 {
278 return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA256);
279 }
280
281 #if defined(MBEDTLS_SHA1_C) || defined(CONFIG_PSA_WANT_ALG_SHA_1)
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)282 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
283 {
284 return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_SHA1);
285 }
286 #endif
287
288 #if defined(MBEDTLS_MD5_C) || defined(CONFIG_PSA_WANT_ALG_MD5)
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)289 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
290 {
291 return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD5);
292 }
293 #endif
294
295 #ifdef MBEDTLS_MD4_C
296 #include <mbedtls/md4.h>
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)297 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
298 {
299 return md_vector(num_elem, addr, len, mac, MBEDTLS_MD_MD4);
300 }
301 #endif
302
303 struct crypto_hash
304 {
305 mbedtls_md_context_t ctx;
306 };
307
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)308 struct crypto_hash *crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, size_t key_len)
309 {
310 struct crypto_hash *ctx;
311 mbedtls_md_type_t md_type;
312 const mbedtls_md_info_t *md_info;
313 int ret = 0;
314
315 switch (alg)
316 {
317 case CRYPTO_HASH_ALG_HMAC_MD5:
318 md_type = MBEDTLS_MD_MD5;
319 break;
320 case CRYPTO_HASH_ALG_HMAC_SHA1:
321 md_type = MBEDTLS_MD_SHA1;
322 break;
323 case CRYPTO_HASH_ALG_HMAC_SHA256:
324 md_type = MBEDTLS_MD_SHA256;
325 break;
326 case CRYPTO_HASH_ALG_SHA384:
327 md_type = MBEDTLS_MD_SHA384;
328 break;
329 case CRYPTO_HASH_ALG_SHA512:
330 md_type = MBEDTLS_MD_SHA512;
331 break;
332 default:
333 return NULL;
334 }
335
336 ctx = os_zalloc(sizeof(*ctx));
337 if (ctx == NULL)
338 {
339 return NULL;
340 }
341
342 mbedtls_md_init(&ctx->ctx);
343 md_info = mbedtls_md_info_from_type(md_type);
344 if (!md_info)
345 {
346 os_free(ctx);
347 return NULL;
348 }
349 ret = mbedtls_md_setup(&ctx->ctx, md_info, 1);
350 if (ret != 0)
351 {
352 os_free(ctx);
353 return NULL;
354 }
355 mbedtls_md_hmac_starts(&ctx->ctx, key, key_len);
356
357 return ctx;
358 }
359
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)360 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
361 {
362 if (ctx == NULL)
363 {
364 return;
365 }
366 mbedtls_md_hmac_update(&ctx->ctx, data, len);
367 }
368
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)369 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
370 {
371 if (ctx == NULL)
372 {
373 return -2;
374 }
375
376 if (mac == NULL || len == NULL)
377 {
378 mbedtls_md_free(&ctx->ctx);
379 bin_clear_free(ctx, sizeof(*ctx));
380 return 0;
381 }
382 mbedtls_md_hmac_finish(&ctx->ctx, mac);
383 mbedtls_md_free(&ctx->ctx);
384 bin_clear_free(ctx, sizeof(*ctx));
385
386 return 0;
387 }
388
hmac_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,mbedtls_md_type_t md_type)389 __attribute_noinline__ static int hmac_vector(const u8 *key,
390 size_t key_len,
391 size_t num_elem,
392 const u8 *addr[],
393 const size_t *len,
394 u8 *mac,
395 mbedtls_md_type_t md_type)
396 {
397 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
398 return hmac_vector_psa(key, key_len, num_elem, addr, len, mac, md_type);
399 #else
400 if (TEST_FAIL())
401 return -1;
402
403 mbedtls_md_context_t ctx;
404 mbedtls_md_init(&ctx);
405 if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1) != 0)
406 {
407 mbedtls_md_free(&ctx);
408 return -1;
409 }
410 mbedtls_md_hmac_starts(&ctx, key, key_len);
411 for (size_t i = 0; i < num_elem; ++i)
412 mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
413 mbedtls_md_hmac_finish(&ctx, mac);
414 mbedtls_md_free(&ctx);
415 return 0;
416 #endif
417 }
418
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)419 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
420 {
421 return hmac_vector(key, key_len, num_elem, addr, len, mac, MBEDTLS_MD_SHA512);
422 }
423
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)424 int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
425 {
426 return hmac_vector(key, key_len, 1, &data, &data_len, mac, MBEDTLS_MD_SHA512);
427 }
428
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)429 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
430 {
431 return hmac_vector(key, key_len, num_elem, addr, len, mac, MBEDTLS_MD_SHA384);
432 }
433
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)434 int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
435 {
436 return hmac_vector(key, key_len, 1, &data, &data_len, mac, MBEDTLS_MD_SHA384);
437 }
438
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)439 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
440 {
441 return hmac_vector(key, key_len, num_elem, addr, len, mac, MBEDTLS_MD_SHA256);
442 }
443
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)444 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
445 {
446 return hmac_vector(key, key_len, 1, &data, &data_len, mac, MBEDTLS_MD_SHA256);
447 }
448
449 #if defined(MBEDTLS_SHA1_C) || defined(CONFIG_PSA_WANT_ALG_SHA_1)
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)450 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
451 {
452 return hmac_vector(key, key_len, num_elem, addr, len, mac, MBEDTLS_MD_SHA1);
453 }
454
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)455 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
456 {
457 return hmac_vector(key, key_len, 1, &data, &data_len, mac, MBEDTLS_MD_SHA1);
458 }
459 #endif
460
461 #if defined(MBEDTLS_MD5_C) || defined(CONFIG_PSA_WANT_ALG_MD5)
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)462 int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
463 {
464 return hmac_vector(key, key_len, num_elem, addr, len, mac, MBEDTLS_MD_MD5);
465 }
466
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)467 int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
468 {
469 return hmac_vector(key, key_len, 1, &data, &data_len, mac, MBEDTLS_MD_MD5);
470 }
471 #endif
472
473 #ifdef MBEDTLS_HKDF_C
474 #include <mbedtls/hkdf.h>
475
476 /* sha256-kdf.c sha384-kdf.c sha512-kdf.c */
477
478 /* HMAC-SHA256 KDF (RFC 5295) and HKDF-Expand(SHA256) (RFC 5869) */
479 /* HMAC-SHA384 KDF (RFC 5295) and HKDF-Expand(SHA384) (RFC 5869) */
480 /* HMAC-SHA512 KDF (RFC 5295) and HKDF-Expand(SHA512) (RFC 5869) */
hmac_kdf_expand(const u8 * prk,size_t prk_len,const char * label,const u8 * info,size_t info_len,u8 * okm,size_t okm_len,mbedtls_md_type_t md_type)481 __attribute_noinline__ static int hmac_kdf_expand(const u8 *prk,
482 size_t prk_len,
483 const char *label,
484 const u8 *info,
485 size_t info_len,
486 u8 *okm,
487 size_t okm_len,
488 mbedtls_md_type_t md_type)
489 {
490 if (TEST_FAIL())
491 return -1;
492
493 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type);
494 if (label == NULL) /* RFC 5869 HKDF-Expand when (label == NULL) */
495 return mbedtls_hkdf_expand(md_info, prk, prk_len, info, info_len, okm, okm_len) ? -1 : 0;
496
497 const size_t mac_len = mbedtls_md_get_size(md_info);
498 /* okm_len must not exceed 255 times hash len (RFC 5869 Section 2.3) */
499 if (okm_len > ((mac_len << 8) - mac_len))
500 return -1;
501
502 mbedtls_md_context_t ctx;
503 mbedtls_md_init(&ctx);
504 if (mbedtls_md_setup(&ctx, md_info, 1) != 0)
505 {
506 mbedtls_md_free(&ctx);
507 return -1;
508 }
509 mbedtls_md_hmac_starts(&ctx, prk, prk_len);
510
511 u8 iter = 1;
512 const u8 *addr[4] = {okm, (const u8 *)label, info, &iter};
513 size_t len[4] = {0, label ? os_strlen(label) + 1 : 0, info_len, 1};
514
515 for (; okm_len >= mac_len; okm_len -= mac_len, ++iter)
516 {
517 for (size_t i = 0; i < ARRAY_SIZE(addr); ++i)
518 mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
519 mbedtls_md_hmac_finish(&ctx, okm);
520 mbedtls_md_hmac_reset(&ctx);
521 addr[0] = okm;
522 okm += mac_len;
523 len[0] = mac_len; /*(include digest in subsequent rounds)*/
524 }
525
526 if (okm_len)
527 {
528 u8 hash[MBEDTLS_MD_MAX_SIZE];
529 for (size_t i = 0; i < ARRAY_SIZE(addr); ++i)
530 mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
531 mbedtls_md_hmac_finish(&ctx, hash);
532 os_memcpy(okm, hash, okm_len);
533 forced_memzero(hash, mac_len);
534 }
535
536 mbedtls_md_free(&ctx);
537 return 0;
538 }
539
hmac_sha512_kdf(const u8 * secret,size_t secret_len,const char * label,const u8 * seed,size_t seed_len,u8 * out,size_t outlen)540 int hmac_sha512_kdf(
541 const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
542 {
543 return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, out, outlen, MBEDTLS_MD_SHA512);
544 }
545
hmac_sha384_kdf(const u8 * secret,size_t secret_len,const char * label,const u8 * seed,size_t seed_len,u8 * out,size_t outlen)546 int hmac_sha384_kdf(
547 const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
548 {
549 return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, out, outlen, MBEDTLS_MD_SHA384);
550 }
551
hmac_sha256_kdf(const u8 * secret,size_t secret_len,const char * label,const u8 * seed,size_t seed_len,u8 * out,size_t outlen)552 int hmac_sha256_kdf(
553 const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
554 {
555 return hmac_kdf_expand(secret, secret_len, label, seed, seed_len, out, outlen, MBEDTLS_MD_SHA256);
556 }
557 #endif /* MBEDTLS_HKDF_C */
558
559 /* sha256-prf.c sha384-prf.c sha512-prf.c */
560
561 /* hmac_prf_bits - IEEE Std 802.11ac-2013, 11.6.1.7.2 Key derivation function */
hmac_prf_bits(const u8 * key,size_t key_len,const char * label,const u8 * data,size_t data_len,u8 * buf,size_t buf_len_bits,mbedtls_md_type_t md_type)562 __attribute_noinline__ static int hmac_prf_bits(const u8 *key,
563 size_t key_len,
564 const char *label,
565 const u8 *data,
566 size_t data_len,
567 u8 *buf,
568 size_t buf_len_bits,
569 mbedtls_md_type_t md_type)
570 {
571 if (TEST_FAIL())
572 return -1;
573
574 mbedtls_md_context_t ctx;
575 mbedtls_md_init(&ctx);
576 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type);
577 if (mbedtls_md_setup(&ctx, md_info, 1) != 0)
578 {
579 mbedtls_md_free(&ctx);
580 return -1;
581 }
582 mbedtls_md_hmac_starts(&ctx, key, key_len);
583
584 u16 ctr, n_le = host_to_le16(buf_len_bits);
585 const u8 *const addr[] = {(u8 *)&ctr, (u8 *)label, data, (u8 *)&n_le};
586 const size_t len[] = {2, os_strlen(label), data_len, 2};
587 const size_t mac_len = mbedtls_md_get_size(md_info);
588 size_t buf_len = (buf_len_bits + 7) / 8;
589 for (ctr = 1; buf_len >= mac_len; buf_len -= mac_len, ++ctr)
590 {
591 #if __BYTE_ORDER == __BIG_ENDIAN
592 ctr = host_to_le16(ctr);
593 #endif
594 for (size_t i = 0; i < ARRAY_SIZE(addr); ++i)
595 mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
596 mbedtls_md_hmac_finish(&ctx, buf);
597 mbedtls_md_hmac_reset(&ctx);
598 buf += mac_len;
599 #if __BYTE_ORDER == __BIG_ENDIAN
600 ctr = le_to_host16(ctr);
601 #endif
602 }
603
604 if (buf_len)
605 {
606 u8 hash[MBEDTLS_MD_MAX_SIZE];
607 #if __BYTE_ORDER == __BIG_ENDIAN
608 ctr = host_to_le16(ctr);
609 #endif
610 for (size_t i = 0; i < ARRAY_SIZE(addr); ++i)
611 mbedtls_md_hmac_update(&ctx, addr[i], len[i]);
612 mbedtls_md_hmac_finish(&ctx, hash);
613 os_memcpy(buf, hash, buf_len);
614 buf += buf_len;
615 forced_memzero(hash, mac_len);
616 }
617
618 /* Mask out unused bits in last octet if it does not use all the bits */
619 if ((buf_len_bits &= 0x7))
620 buf[-1] &= (u8)(0xff << (8 - buf_len_bits));
621
622 mbedtls_md_free(&ctx);
623 return 0;
624 }
625
sha512_prf(const u8 * key,size_t key_len,const char * label,const u8 * data,size_t data_len,u8 * buf,size_t buf_len)626 int sha512_prf(
627 const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
628 {
629 return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8, MBEDTLS_MD_SHA512);
630 }
631
sha384_prf(const u8 * key,size_t key_len,const char * label,const u8 * data,size_t data_len,u8 * buf,size_t buf_len)632 int sha384_prf(
633 const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
634 {
635 return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8, MBEDTLS_MD_SHA384);
636 }
637
638 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
639 /**
640 * Based on Supplicant internal implementaion of SHA-256. This API
641 * uses PSA APIs instead of Supplicant internal implementation or
642 * mbedtls APIs.
643 */
hmac_prf256(const u8 * key,size_t key_len,const char * label,const u8 * data,size_t data_len,u8 * buf_in,size_t buf_len_bits,mbedtls_md_type_t md_type)644 static int hmac_prf256(const u8 *key,
645 size_t key_len,
646 const char *label,
647 const u8 *data,
648 size_t data_len,
649 u8 *buf_in,
650 size_t buf_len_bits,
651 mbedtls_md_type_t md_type)
652 {
653 unsigned short ctr, n_le = host_to_le16(buf_len_bits);
654 const u8 *addr[] = {(u8 *)&ctr, (u8 *)label, data, (u8 *)&n_le};
655 const size_t len[] = {2, os_strlen(label), data_len, 2};
656 size_t buf_len = (buf_len_bits + 7) / 8;
657 u8 *buf = buf_in;
658
659 for (ctr = 1; buf_len >= SHA256_MAC_LEN; buf_len -= SHA256_MAC_LEN, ++ctr)
660 {
661 if (hmac_sha256_vector(key, key_len, 4, addr, len, buf))
662 return -1;
663 buf += SHA256_MAC_LEN;
664 }
665
666 if (buf_len)
667 {
668 u8 hash[SHA256_MAC_LEN];
669 if (hmac_sha256_vector(key, key_len, 4, addr, len, hash))
670 return -1;
671 os_memcpy(buf, hash, buf_len);
672 forced_memzero(hash, sizeof(hash));
673 }
674
675 /* Mask out unused bits in last octet if it does not use all the bits */
676 if ((buf_len_bits &= 0x7))
677 buf[-1] &= (u8)(0xff << (8 - buf_len_bits));
678
679 return 0;
680 }
681 #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA */
682
sha256_prf(const u8 * key,size_t key_len,const char * label,const u8 * data,size_t data_len,u8 * buf,size_t buf_len)683 int sha256_prf(
684 const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
685 {
686 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
687 return hmac_prf256(key, key_len, label, data, data_len, buf, buf_len * 8, MBEDTLS_MD_SHA256);
688 #else
689 return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len * 8, MBEDTLS_MD_SHA256);
690 #endif
691 }
692
sha256_prf_bits(const u8 * key,size_t key_len,const char * label,const u8 * data,size_t data_len,u8 * buf,size_t buf_len_bits)693 int sha256_prf_bits(
694 const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len_bits)
695 {
696 return hmac_prf_bits(key, key_len, label, data, data_len, buf, buf_len_bits, MBEDTLS_MD_SHA256);
697 }
698
699 #if defined(MBEDTLS_SHA1_C) || defined(CONFIG_PSA_WANT_ALG_SHA_1)
700
701 /* sha1-prf.c */
702
703 /* sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) */
704
sha1_prf(const u8 * key,size_t key_len,const char * label,const u8 * data,size_t data_len,u8 * buf,size_t buf_len)705 int sha1_prf(const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
706 {
707 /*(note: algorithm differs from hmac_prf_bits() */
708 /*(note: smaller code size instead of expanding hmac_sha1_vector()
709 * as is done in hmac_prf_bits(); not expecting large num of loops) */
710 u8 counter = 0;
711 const u8 *addr[] = {(u8 *)label, data, &counter};
712 const size_t len[] = {os_strlen(label) + 1, data_len, 1};
713
714 for (; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++counter)
715 {
716 if (hmac_sha1_vector(key, key_len, 3, addr, len, buf))
717 return -1;
718 buf += SHA1_MAC_LEN;
719 }
720
721 if (buf_len)
722 {
723 u8 hash[SHA1_MAC_LEN];
724 if (hmac_sha1_vector(key, key_len, 3, addr, len, hash))
725 return -1;
726 os_memcpy(buf, hash, buf_len);
727 forced_memzero(hash, sizeof(hash));
728 }
729
730 return 0;
731 }
732
733 #ifdef CRYPTO_MBEDTLS_SHA1_T_PRF
734
735 /* sha1-tprf.c */
736
737 /* sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF) (RFC 4851,Section 5.5)*/
738
sha1_t_prf(const u8 * key,size_t key_len,const char * label,const u8 * seed,size_t seed_len,u8 * buf,size_t buf_len)739 int sha1_t_prf(
740 const u8 *key, size_t key_len, const char *label, const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len)
741 {
742 /*(note: algorithm differs from hmac_prf_bits() and hmac_kdf() above)*/
743 /*(note: smaller code size instead of expanding hmac_sha1_vector()
744 * as is done in hmac_prf_bits(); not expecting large num of loops) */
745 u8 ctr;
746 u16 olen = host_to_be16(buf_len);
747 const u8 *addr[] = {buf, (u8 *)label, seed, (u8 *)&olen, &ctr};
748 size_t len[] = {0, os_strlen(label) + 1, seed_len, 2, 1};
749
750 for (ctr = 1; buf_len >= SHA1_MAC_LEN; buf_len -= SHA1_MAC_LEN, ++ctr)
751 {
752 if (hmac_sha1_vector(key, key_len, 5, addr, len, buf))
753 return -1;
754 addr[0] = buf;
755 buf += SHA1_MAC_LEN;
756 len[0] = SHA1_MAC_LEN; /*(include digest in subsequent rounds)*/
757 }
758
759 if (buf_len)
760 {
761 u8 hash[SHA1_MAC_LEN];
762 if (hmac_sha1_vector(key, key_len, 5, addr, len, hash))
763 return -1;
764 os_memcpy(buf, hash, buf_len);
765 forced_memzero(hash, sizeof(hash));
766 }
767
768 return 0;
769 }
770
771 #endif /* CRYPTO_MBEDTLS_SHA1_T_PRF */
772 #endif /* MBEDTLS_SHA1_C || CONFIG_PSA_WANT_ALG_SHA_1 */
773
774 #ifdef MBEDTLS_DES_C
775 #include <mbedtls/des.h>
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)776 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
777 {
778 u8 pkey[8], next, tmp;
779 int i;
780
781 /* Add parity bits to the key */
782 next = 0;
783 for (i = 0; i < 7; i++)
784 {
785 tmp = key[i];
786 pkey[i] = (tmp >> i) | next | 1;
787 next = tmp << (7 - i);
788 }
789 pkey[i] = next | 1;
790
791 mbedtls_des_context des;
792 mbedtls_des_init(&des);
793 int ret = mbedtls_des_setkey_enc(&des, pkey) || mbedtls_des_crypt_ecb(&des, clear, cypher) ? -1 : 0;
794 mbedtls_des_free(&des);
795 return ret;
796 }
797 #endif
798
799 #ifdef CRYPTO_MBEDTLS_PBKDF2_SHA1
800 /* sha1-pbkdf2.c */
801 #include <mbedtls/pkcs5.h>
pbkdf2_sha1(const char * passphrase,const u8 * ssid,size_t ssid_len,int iterations,u8 * buf,size_t buflen)802 int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, int iterations, u8 *buf, size_t buflen)
803 {
804 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
805 return pbkdf2_sha1_psa(MBEDTLS_MD_SHA1, (const u8 *)passphrase,
806 os_strlen(passphrase), ssid, ssid_len,
807 iterations, 32, buf) ? -1: 0;
808 #else
809 #if MBEDTLS_VERSION_NUMBER >= 0x03020200 /* mbedtls 3.2.2 */
810 return mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const u8 *)passphrase, os_strlen(passphrase), ssid, ssid_len,
811 iterations, 32, buf) ?
812 -1 :
813 0;
814 #else
815 const mbedtls_md_info_t *md_info;
816 md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
817 if (md_info == NULL)
818 return -1;
819 mbedtls_md_context_t ctx;
820 mbedtls_md_init(&ctx);
821 int ret = mbedtls_md_setup(&ctx, md_info, 1) ||
822 mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const u8 *)passphrase, os_strlen(passphrase), ssid, ssid_len,
823 iterations, 32, buf) ?
824 -1 :
825 0;
826 mbedtls_md_free(&ctx);
827 return ret;
828 #endif
829 #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA */
830 }
831 #endif
832
833 #include "aes_wrap.h"
834
835 #ifdef MBEDTLS_NIST_KW_C
836
837 #include <mbedtls/nist_kw.h>
838
839 /* aes-wrap.c */
aes_wrap(const u8 * kek,size_t kek_len,int n,const u8 * plain,u8 * cipher)840 int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
841 {
842 if (TEST_FAIL())
843 return -1;
844
845 mbedtls_nist_kw_context ctx;
846 mbedtls_nist_kw_init(&ctx);
847 size_t olen;
848 int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, kek, kek_len * 8, 1) ||
849 mbedtls_nist_kw_wrap(&ctx, MBEDTLS_KW_MODE_KW, plain, n * 8, cipher, &olen, (n + 1) * 8) ?
850 -1 :
851 0;
852 mbedtls_nist_kw_free(&ctx);
853 return ret;
854 }
855
856 /* aes-unwrap.c */
aes_unwrap(const u8 * kek,size_t kek_len,int n,const u8 * cipher,u8 * plain)857 int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain)
858 {
859 if (TEST_FAIL())
860 return -1;
861
862 mbedtls_nist_kw_context ctx;
863 mbedtls_nist_kw_init(&ctx);
864 size_t olen;
865 int ret = mbedtls_nist_kw_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, kek, kek_len * 8, 0) ||
866 mbedtls_nist_kw_unwrap(&ctx, MBEDTLS_KW_MODE_KW, cipher, (n + 1) * 8, plain, &olen, n * 8) ?
867 -1 :
868 0;
869 mbedtls_nist_kw_free(&ctx);
870 return ret;
871 }
872 #endif /* MBEDTLS_NIST_KW_C */
873
874 #if defined(MBEDTLS_CMAC_C) || defined(CONFIG_PSA_WANT_ALG_CMAC)
875
876 /* aes-omac1.c */
877
878 #include <mbedtls/cmac.h>
879
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)880 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
881 {
882 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
883 return omac1_aes_vector_psa(key, key_len, num_elem, addr, len, mac);
884 #else
885 if (TEST_FAIL())
886 return -1;
887
888 mbedtls_cipher_type_t cipher_type;
889 switch (key_len)
890 {
891 case 16:
892 cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
893 break;
894 case 24:
895 cipher_type = MBEDTLS_CIPHER_AES_192_ECB;
896 break;
897 case 32:
898 cipher_type = MBEDTLS_CIPHER_AES_256_ECB;
899 break;
900 default:
901 return -1;
902 }
903 const mbedtls_cipher_info_t *cipher_info;
904 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
905 if (cipher_info == NULL)
906 return -1;
907
908 mbedtls_cipher_context_t ctx;
909 mbedtls_cipher_init(&ctx);
910 int ret = -1;
911 if (mbedtls_cipher_setup(&ctx, cipher_info) == 0 && mbedtls_cipher_cmac_starts(&ctx, key, key_len * 8) == 0)
912 {
913 ret = 0;
914 for (size_t i = 0; i < num_elem && ret == 0; ++i)
915 ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]);
916 }
917 if (ret == 0)
918 ret = mbedtls_cipher_cmac_finish(&ctx, mac);
919 mbedtls_cipher_free(&ctx);
920 return ret ? -1 : 0;
921 #endif
922 }
923
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)924 int omac1_aes_128_vector(const u8 *key, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
925 {
926 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
927 }
928
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)929 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
930 {
931 return omac1_aes_vector(key, 16, 1, &data, &data_len, mac);
932 }
933
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)934 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
935 {
936 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
937 }
938
939 #else
940
941 //#include "aes-omac1.c" /* pull in hostap local implementation */
942
943 #ifndef MBEDTLS_AES_BLOCK_SIZE
944 #define MBEDTLS_AES_BLOCK_SIZE 16
945 #endif
946
947 #endif /* MBEDTLS_CMAC_C */
948
949 #if defined(MBEDTLS_AES_C) || defined(CONFIG_PSA_WANT_KEY_TYPE_AES)
950
951 /* These interfaces can be inefficient when used in loops, as the overhead of
952 * initialization each call is large for each block input (e.g. 16 bytes) */
953
954 /* aes-encblock.c */
aes_128_encrypt_block(const u8 * key,const u8 * in,u8 * out)955 int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out)
956 {
957 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
958 return aes_128_encrypt_block_psa(key, in, out);
959 #else
960 if (TEST_FAIL())
961 return -1;
962
963 mbedtls_aes_context aes;
964 mbedtls_aes_init(&aes);
965 int ret =
966 mbedtls_aes_setkey_enc(&aes, key, 128) || mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, in, out) ? -1 : 0;
967 mbedtls_aes_free(&aes);
968 return ret;
969 #endif
970 }
971
972 /* aes-ctr.c */
aes_ctr_encrypt(const u8 * key,size_t key_len,const u8 * nonce,u8 * data,size_t data_len)973 int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, u8 *data, size_t data_len)
974 {
975 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
976 return aes_ctr_encrypt_psa(key, key_len, nonce, data, data_len);
977 #else
978 if (TEST_FAIL())
979 return -1;
980
981 unsigned char counter[MBEDTLS_AES_BLOCK_SIZE];
982 unsigned char stream_block[MBEDTLS_AES_BLOCK_SIZE];
983 os_memcpy(counter, nonce, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/
984
985 mbedtls_aes_context ctx;
986 mbedtls_aes_init(&ctx);
987 size_t nc_off = 0;
988 int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len * 8) ||
989 mbedtls_aes_crypt_ctr(&ctx, data_len, &nc_off, counter, stream_block, data, data) ?
990 -1 :
991 0;
992 forced_memzero(stream_block, sizeof(stream_block));
993 mbedtls_aes_free(&ctx);
994 return ret;
995 #endif
996 }
997
aes_128_ctr_encrypt(const u8 * key,const u8 * nonce,u8 * data,size_t data_len)998 int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, u8 *data, size_t data_len)
999 {
1000 return aes_ctr_encrypt(key, 16, nonce, data, data_len);
1001 }
1002
1003 /* aes-cbc.c */
aes_128_cbc_oper(const u8 * key,const u8 * iv,u8 * data,size_t data_len,int mode)1004 static int aes_128_cbc_oper(const u8 *key, const u8 *iv, u8 *data, size_t data_len, int mode)
1005 {
1006 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_MBEDTLS_PSA
1007 if (mode == MBEDTLS_AES_ENCRYPT)
1008 return aes_128_cbc_encrypt_psa(key, iv, data, data_len);
1009 else
1010 return aes_128_cbc_decrypt_psa(key, iv, data, data_len);
1011 #else
1012 unsigned char ivec[MBEDTLS_AES_BLOCK_SIZE];
1013 os_memcpy(ivec, iv, MBEDTLS_AES_BLOCK_SIZE); /*(must be writable)*/
1014
1015 mbedtls_aes_context ctx;
1016 mbedtls_aes_init(&ctx);
1017 int ret = (mode == MBEDTLS_AES_ENCRYPT ? mbedtls_aes_setkey_enc(&ctx, key, 128) :
1018 mbedtls_aes_setkey_dec(&ctx, key, 128)) ||
1019 mbedtls_aes_crypt_cbc(&ctx, mode, data_len, ivec, data, data);
1020 mbedtls_aes_free(&ctx);
1021 return ret ? -1 : 0;
1022 #endif
1023 }
1024
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)1025 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
1026 {
1027 if (TEST_FAIL())
1028 return -1;
1029
1030 return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_ENCRYPT);
1031 }
1032
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)1033 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
1034 {
1035 if (TEST_FAIL())
1036 return -1;
1037
1038 return aes_128_cbc_oper(key, iv, data, data_len, MBEDTLS_AES_DECRYPT);
1039 }
1040 #endif
1041
1042 /*
1043 * Much of the following is documented in crypto.h as for CONFIG_TLS=internal
1044 * but such comments are not accurate:
1045 *
1046 * "This function is only used with internal TLSv1 implementation
1047 * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
1048 * to implement this."
1049 */
1050
1051 #ifdef CRYPTO_MBEDTLS_CRYPTO_CIPHER
1052
1053 #include <mbedtls/cipher.h>
1054
1055 struct crypto_cipher
1056 {
1057 mbedtls_cipher_context_t ctx_enc;
1058 mbedtls_cipher_context_t ctx_dec;
1059 };
1060
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)1061 struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg, const u8 *iv, const u8 *key, size_t key_len)
1062 {
1063 /* IKEv2 src/eap_common/ikev2_common.c:ikev2_{encr,decr}_encrypt()
1064 * uses one of CRYPTO_CIPHER_ALG_AES or CRYPTO_CIPHER_ALG_3DES */
1065
1066 mbedtls_cipher_type_t cipher_type;
1067 size_t iv_len;
1068 switch (alg)
1069 {
1070 #ifdef MBEDTLS_AES_C
1071 case CRYPTO_CIPHER_ALG_AES:
1072 if (key_len == 16)
1073 cipher_type = MBEDTLS_CIPHER_AES_128_CTR;
1074 if (key_len == 24)
1075 cipher_type = MBEDTLS_CIPHER_AES_192_CTR;
1076 if (key_len == 32)
1077 cipher_type = MBEDTLS_CIPHER_AES_256_CTR;
1078 iv_len = 16;
1079 break;
1080 #endif
1081 #ifdef MBEDTLS_DES_C
1082 case CRYPTO_CIPHER_ALG_3DES:
1083 cipher_type = MBEDTLS_CIPHER_DES_EDE3_CBC;
1084 iv_len = 8;
1085 break;
1086 #endif
1087 default:
1088 return NULL;
1089 }
1090
1091 const mbedtls_cipher_info_t *cipher_info;
1092 cipher_info = mbedtls_cipher_info_from_type(cipher_type);
1093 if (cipher_info == NULL)
1094 return NULL;
1095
1096 key_len *= 8; /* key_bitlen */
1097
1098 struct crypto_cipher *ctx = os_malloc(sizeof(*ctx));
1099 if (!ctx)
1100 return NULL;
1101
1102 mbedtls_cipher_init(&ctx->ctx_enc);
1103 mbedtls_cipher_init(&ctx->ctx_dec);
1104 if (mbedtls_cipher_setup(&ctx->ctx_enc, cipher_info) == 0 &&
1105 mbedtls_cipher_setup(&ctx->ctx_dec, cipher_info) == 0 &&
1106 mbedtls_cipher_setkey(&ctx->ctx_enc, key, key_len, MBEDTLS_ENCRYPT) == 0 &&
1107 mbedtls_cipher_setkey(&ctx->ctx_dec, key, key_len, MBEDTLS_DECRYPT) == 0 &&
1108 mbedtls_cipher_set_iv(&ctx->ctx_enc, iv, iv_len) == 0 &&
1109 mbedtls_cipher_set_iv(&ctx->ctx_dec, iv, iv_len) == 0 && mbedtls_cipher_reset(&ctx->ctx_enc) == 0 &&
1110 mbedtls_cipher_reset(&ctx->ctx_dec) == 0)
1111 {
1112 return ctx;
1113 }
1114
1115 mbedtls_cipher_free(&ctx->ctx_enc);
1116 mbedtls_cipher_free(&ctx->ctx_dec);
1117 os_free(ctx);
1118 return NULL;
1119 }
1120
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)1121 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, u8 *crypt, size_t len)
1122 {
1123 size_t olen = 0; /*(poor interface above; unknown size of u8 *crypt)*/
1124 return (mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen) ||
1125 mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen)) ?
1126 -1 :
1127 0;
1128 }
1129
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)1130 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, u8 *plain, size_t len)
1131 {
1132 size_t olen = 0; /*(poor interface above; unknown size of u8 *plain)*/
1133 return (mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen) ||
1134 mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen)) ?
1135 -1 :
1136 0;
1137 }
1138
crypto_cipher_deinit(struct crypto_cipher * ctx)1139 void crypto_cipher_deinit(struct crypto_cipher *ctx)
1140 {
1141 mbedtls_cipher_free(&ctx->ctx_enc);
1142 mbedtls_cipher_free(&ctx->ctx_dec);
1143 os_free(ctx);
1144 }
1145
1146 #endif /* CRYPTO_MBEDTLS_CRYPTO_CIPHER */
1147
1148 #ifdef CRYPTO_MBEDTLS_CRYPTO_BIGNUM
1149
1150 #include <mbedtls/bignum.h>
1151
1152 /* crypto.h bignum interfaces */
1153
crypto_bignum_init(void)1154 struct crypto_bignum *crypto_bignum_init(void)
1155 {
1156 if (TEST_FAIL())
1157 return NULL;
1158
1159 mbedtls_mpi *bn = os_malloc(sizeof(*bn));
1160 if (bn)
1161 mbedtls_mpi_init(bn);
1162 return (struct crypto_bignum *)bn;
1163 }
1164
crypto_bignum_init_set(const u8 * buf,size_t len)1165 struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len)
1166 {
1167 if (TEST_FAIL())
1168 return NULL;
1169
1170 mbedtls_mpi *bn = os_malloc(sizeof(*bn));
1171 if (bn)
1172 {
1173 mbedtls_mpi_init(bn);
1174 if (mbedtls_mpi_read_binary(bn, buf, len) == 0)
1175 return (struct crypto_bignum *)bn;
1176 }
1177
1178 os_free(bn);
1179 return NULL;
1180 }
1181
crypto_bignum_init_uint(unsigned int val)1182 struct crypto_bignum *crypto_bignum_init_uint(unsigned int val)
1183 {
1184 if (TEST_FAIL())
1185 return NULL;
1186
1187 mbedtls_mpi *bn = os_malloc(sizeof(*bn));
1188 if (bn)
1189 {
1190 mbedtls_mpi_init(bn);
1191 if (mbedtls_mpi_lset(bn, (int)val) == 0)
1192 return (struct crypto_bignum *)bn;
1193 }
1194
1195 os_free(bn);
1196 return NULL;
1197 }
1198
crypto_bignum_deinit(struct crypto_bignum * n,int clear)1199 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1200 {
1201 mbedtls_mpi_free((mbedtls_mpi *)n);
1202 os_free(n);
1203 }
1204
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)1205 int crypto_bignum_to_bin(const struct crypto_bignum *a, u8 *buf, size_t buflen, size_t padlen)
1206 {
1207 if (TEST_FAIL())
1208 return -1;
1209
1210 size_t n = mbedtls_mpi_size((mbedtls_mpi *)a);
1211 if (n < padlen)
1212 n = padlen;
1213 return n > buflen || mbedtls_mpi_write_binary((mbedtls_mpi *)a, buf, n) ? -1 : (int)(n);
1214 }
1215
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)1216 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
1217 {
1218 if (TEST_FAIL())
1219 return -1;
1220
1221 /*assert(r != m);*/ /* r must not be same as m for mbedtls_mpi_random()*/
1222 #if MBEDTLS_VERSION_NUMBER >= 0x021B0000 /* mbedtls 2.27.0 */
1223 return mbedtls_mpi_random((mbedtls_mpi *)r, 0, (mbedtls_mpi *)m, hostap_rng_fn, hostap_rng_ctx()) ?
1224 -1 :
1225 0;
1226 #else
1227 /* (needed by EAP_PWD, SAE, DPP) */
1228 wpa_printf(MSG_ERROR, "mbedtls 2.27.0 or later required for mbedtls_mpi_random()");
1229 return -1;
1230 #endif
1231 }
1232
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1233 int crypto_bignum_add(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
1234 {
1235 return mbedtls_mpi_add_mpi((mbedtls_mpi *)c, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b) ? -1 : 0;
1236 }
1237
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1238 int crypto_bignum_mod(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
1239 {
1240 return mbedtls_mpi_mod_mpi((mbedtls_mpi *)c, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b) ? -1 : 0;
1241 }
1242
crypto_bignum_exptmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)1243 int crypto_bignum_exptmod(const struct crypto_bignum *a,
1244 const struct crypto_bignum *b,
1245 const struct crypto_bignum *c,
1246 struct crypto_bignum *d)
1247 {
1248 if (TEST_FAIL())
1249 return -1;
1250
1251 /* (check if input params match d; d is the result) */
1252 /* (a == d) is ok in current mbedtls implementation */
1253 if (b == d || c == d)
1254 { /*(not ok; store result in intermediate)*/
1255 mbedtls_mpi R;
1256 mbedtls_mpi_init(&R);
1257 int rc =
1258 mbedtls_mpi_exp_mod(&R, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b, (const mbedtls_mpi *)c, NULL) ||
1259 mbedtls_mpi_copy((mbedtls_mpi *)d, &R) ?
1260 -1 :
1261 0;
1262 mbedtls_mpi_free(&R);
1263 return rc;
1264 }
1265 else
1266 {
1267 return mbedtls_mpi_exp_mod((mbedtls_mpi *)d, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b,
1268 (const mbedtls_mpi *)c, NULL) ?
1269 -1 :
1270 0;
1271 }
1272 }
1273
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1274 int crypto_bignum_inverse(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
1275 {
1276 if (TEST_FAIL())
1277 return -1;
1278
1279 return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b) ? -1 : 0;
1280 }
1281
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1282 int crypto_bignum_sub(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
1283 {
1284 if (TEST_FAIL())
1285 return -1;
1286
1287 return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b) ? -1 : 0;
1288 }
1289
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1290 int crypto_bignum_div(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
1291 {
1292 if (TEST_FAIL())
1293 return -1;
1294
1295 /*(most current use of this crypto.h interface has a == c (result),
1296 * so store result in an intermediate to avoid overwritten input)*/
1297 mbedtls_mpi R;
1298 mbedtls_mpi_init(&R);
1299 int rc = mbedtls_mpi_div_mpi(&R, NULL, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b) ||
1300 mbedtls_mpi_copy((mbedtls_mpi *)c, &R) ?
1301 -1 :
1302 0;
1303 mbedtls_mpi_free(&R);
1304 return rc;
1305 }
1306
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)1307 int crypto_bignum_addmod(const struct crypto_bignum *a,
1308 const struct crypto_bignum *b,
1309 const struct crypto_bignum *c,
1310 struct crypto_bignum *d)
1311 {
1312 if (TEST_FAIL())
1313 return -1;
1314
1315 return mbedtls_mpi_add_mpi((mbedtls_mpi *)d, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b) ||
1316 mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, (mbedtls_mpi *)d, (const mbedtls_mpi *)c) ?
1317 -1 :
1318 0;
1319 }
1320
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)1321 int crypto_bignum_mulmod(const struct crypto_bignum *a,
1322 const struct crypto_bignum *b,
1323 const struct crypto_bignum *c,
1324 struct crypto_bignum *d)
1325 {
1326 if (TEST_FAIL())
1327 return -1;
1328
1329 return mbedtls_mpi_mul_mpi((mbedtls_mpi *)d, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b) ||
1330 mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, (mbedtls_mpi *)d, (const mbedtls_mpi *)c) ?
1331 -1 :
1332 0;
1333 }
1334
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1335 int crypto_bignum_sqrmod(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
1336 {
1337 if (TEST_FAIL())
1338 return -1;
1339
1340 #if 1
1341 return crypto_bignum_mulmod(a, a, b, c);
1342 #else
1343 mbedtls_mpi bn;
1344 mbedtls_mpi_init(&bn);
1345 if (mbedtls_mpi_lset(&bn, 2)) /* alt?: mbedtls_mpi_set_bit(&bn, 1) */
1346 return -1;
1347 int ret = mbedtls_mpi_exp_mod((mbedtls_mpi *)c, (const mbedtls_mpi *)a, &bn, (const mbedtls_mpi *)b, NULL) ? -1 : 0;
1348 mbedtls_mpi_free(&bn);
1349 return ret;
1350 #endif
1351 }
1352
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)1353 int crypto_bignum_rshift(const struct crypto_bignum *a, int n, struct crypto_bignum *r)
1354 {
1355 return mbedtls_mpi_copy((mbedtls_mpi *)r, (const mbedtls_mpi *)a) || mbedtls_mpi_shift_r((mbedtls_mpi *)r, n) ? -1 :
1356 0;
1357 }
1358
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)1359 int crypto_bignum_cmp(const struct crypto_bignum *a, const struct crypto_bignum *b)
1360 {
1361 return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
1362 }
1363
crypto_bignum_is_zero(const struct crypto_bignum * a)1364 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1365 {
1366 /* XXX: src/common/sae.c:sswu() contains comment:
1367 * "TODO: Make sure crypto_bignum_is_zero() is constant time"
1368 * Note: mbedtls_mpi_cmp_int() *is not* constant time */
1369 return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 0) == 0);
1370 }
1371
crypto_bignum_is_one(const struct crypto_bignum * a)1372 int crypto_bignum_is_one(const struct crypto_bignum *a)
1373 {
1374 return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 1) == 0);
1375 }
1376
crypto_bignum_is_odd(const struct crypto_bignum * a)1377 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1378 {
1379 return mbedtls_mpi_get_bit((const mbedtls_mpi *)a, 0);
1380 }
1381
1382 #include "utils/const_time.h"
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)1383 int crypto_bignum_legendre(const struct crypto_bignum *a, const struct crypto_bignum *p)
1384 {
1385 if (TEST_FAIL())
1386 return -2;
1387
1388 /* Security Note:
1389 * mbedtls_mpi_exp_mod() is not documented to run in constant time,
1390 * though mbedtls/library/bignum.c uses constant_time_internal.h funcs.
1391 * Compare to crypto_openssl.c:crypto_bignum_legendre()
1392 * which uses openssl BN_mod_exp_mont_consttime()
1393 * mbedtls/library/ecp.c has further countermeasures to timing attacks,
1394 * (but ecp.c funcs are not used here) */
1395
1396 mbedtls_mpi exp, tmp;
1397 mbedtls_mpi_init(&exp);
1398 mbedtls_mpi_init(&tmp);
1399
1400 /* exp = (p-1) / 2 */
1401 int res;
1402 if (mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *)p, 1) == 0 && mbedtls_mpi_shift_r(&exp, 1) == 0 &&
1403 mbedtls_mpi_exp_mod(&tmp, (const mbedtls_mpi *)a, &exp, (const mbedtls_mpi *)p, NULL) == 0)
1404 {
1405 /*(modified from crypto_openssl.c:crypto_bignum_legendre())*/
1406 /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need
1407 * to use constant time selection to avoid branches here. */
1408 unsigned int mask;
1409 res = -1;
1410 mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 1) == 0), 1);
1411 res = const_time_select_int(mask, 1, res);
1412 mask = const_time_eq((mbedtls_mpi_cmp_int(&tmp, 0) == 0), 1);
1413 res = const_time_select_int(mask, 0, res);
1414 }
1415 else
1416 {
1417 res = -2;
1418 }
1419
1420 mbedtls_mpi_free(&tmp);
1421 mbedtls_mpi_free(&exp);
1422 return res;
1423 }
1424
1425 #endif /* CRYPTO_MBEDTLS_CRYPTO_BIGNUM */
1426
1427 #ifdef CRYPTO_MBEDTLS_CRYPTO_DH
1428
1429 /* crypto_internal-modexp.c */
1430
1431 #include <mbedtls/bignum.h>
1432 #include <mbedtls/dhm.h>
1433
crypto_mbedtls_dh_set_bin_pg(mbedtls_dhm_context * ctx,u8 generator,const u8 * prime,size_t prime_len)1434 static int crypto_mbedtls_dh_set_bin_pg(mbedtls_dhm_context *ctx, u8 generator, const u8 *prime, size_t prime_len)
1435 {
1436 /*(could set these directly in MBEDTLS_PRIVATE members)*/
1437 mbedtls_mpi P, G;
1438 mbedtls_mpi_init(&P);
1439 mbedtls_mpi_init(&G);
1440 int ret = mbedtls_mpi_lset(&G, generator) || mbedtls_mpi_read_binary(&P, prime, prime_len) ||
1441 mbedtls_dhm_set_group(ctx, &P, &G);
1442 mbedtls_mpi_free(&P);
1443 mbedtls_mpi_free(&G);
1444 return ret;
1445 }
1446
crypto_mbedtls_dh_init_public(mbedtls_dhm_context * ctx,u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)1447 __attribute_noinline__ static int crypto_mbedtls_dh_init_public(
1448 mbedtls_dhm_context *ctx, u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, u8 *pubkey)
1449 {
1450 if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len) ||
1451 mbedtls_dhm_make_public(ctx, (int)prime_len, pubkey, prime_len, hostap_rng_fn, hostap_rng_ctx()))
1452 return -1;
1453
1454 return mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(X), privkey, prime_len) ? -1 : 0;
1455 }
1456
crypto_dh_init(u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)1457 int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, u8 *pubkey)
1458 {
1459 if (TEST_FAIL())
1460 return -1;
1461
1462 /* Prefer to use mbedtls to derive our public/private key, as doing so
1463 * leverages mbedtls to properly format output and to perform blinding*/
1464 mbedtls_dhm_context ctx;
1465 mbedtls_dhm_init(&ctx);
1466 int ret = crypto_mbedtls_dh_init_public(&ctx, generator, prime, prime_len, privkey, pubkey);
1467 mbedtls_dhm_free(&ctx);
1468 return ret;
1469 }
1470
1471 /*(crypto_dh_derive_secret() could be implemented using crypto.h APIs
1472 * instead of being reimplemented in each crypto_*.c)*/
crypto_dh_derive_secret(u8 generator,const u8 * prime,size_t prime_len,const u8 * order,size_t order_len,const u8 * privkey,size_t privkey_len,const u8 * pubkey,size_t pubkey_len,u8 * secret,size_t * len)1473 int crypto_dh_derive_secret(u8 generator,
1474 const u8 *prime,
1475 size_t prime_len,
1476 const u8 *order,
1477 size_t order_len,
1478 const u8 *privkey,
1479 size_t privkey_len,
1480 const u8 *pubkey,
1481 size_t pubkey_len,
1482 u8 *secret,
1483 size_t *len)
1484 {
1485 if (TEST_FAIL())
1486 return -1;
1487
1488 /* Prefer to use mbedtls to derive DH shared secret, as doing so
1489 * leverages mbedtls to validate params and to perform blinding.
1490 *
1491 * Attempt to reconstitute DH context to derive shared secret
1492 * (due to limitations of the interface, which ought to pass context).
1493 * Force provided G (our private key) into context without validation.
1494 * Regenerating GX (our public key) not needed to derive shared secret.
1495 */
1496 /*(older compilers might not support VLAs)*/
1497 /*unsigned char buf[2+prime_len+2+1+2+pubkey_len];*/
1498 unsigned char buf[2 + MBEDTLS_MPI_MAX_SIZE + 2 + 1 + 2 + MBEDTLS_MPI_MAX_SIZE];
1499 unsigned char *p = buf + 2 + prime_len;
1500 if (2 + prime_len + 2 + 1 + 2 + pubkey_len > sizeof(buf))
1501 return -1;
1502 WPA_PUT_BE16(buf, prime_len); /*(2-byte big-endian size of prime)*/
1503 p[0] = 0; /*(2-byte big-endian size of generator)*/
1504 p[1] = 1;
1505 p[2] = generator;
1506 WPA_PUT_BE16(p + 3, pubkey_len); /*(2-byte big-endian size of pubkey)*/
1507 os_memcpy(p + 5, pubkey, pubkey_len);
1508 os_memcpy(buf + 2, prime, prime_len);
1509
1510 mbedtls_dhm_context ctx;
1511 mbedtls_dhm_init(&ctx);
1512 p = buf;
1513 int ret =
1514 mbedtls_dhm_read_params(&ctx, &p, p + 2 + prime_len + 5 + pubkey_len) ||
1515 mbedtls_mpi_read_binary(&ctx.MBEDTLS_PRIVATE(X), privkey, privkey_len) ||
1516 mbedtls_dhm_calc_secret(&ctx, secret, *len, len, hostap_rng_fn, hostap_rng_ctx()) ?
1517 -1 :
1518 0;
1519 mbedtls_dhm_free(&ctx);
1520 return ret;
1521 }
1522
1523 /* dh_group5.c */
1524
1525 #include "dh_group5.h"
1526
1527 /* RFC3526_PRIME_1536[] and RFC3526_GENERATOR_1536[] from crypto_wolfssl.c */
1528
1529 static const unsigned char RFC3526_PRIME_1536[] = {
1530 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6,
1531 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
1532 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A,
1533 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
1534 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF,
1535 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
1536 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63,
1537 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
1538 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5,
1539 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
1540 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1541
1542 static const unsigned char RFC3526_GENERATOR_1536[] = {0x02};
1543
dh5_init(struct wpabuf ** priv,struct wpabuf ** publ)1544 void *dh5_init(struct wpabuf **priv, struct wpabuf **publ)
1545 {
1546 const unsigned char *const prime = RFC3526_PRIME_1536;
1547 const size_t prime_len = sizeof(RFC3526_PRIME_1536);
1548 const u8 generator = *RFC3526_GENERATOR_1536;
1549 struct wpabuf *wpubl = NULL, *wpriv = NULL;
1550
1551 mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx));
1552 if (ctx == NULL)
1553 return NULL;
1554 mbedtls_dhm_init(ctx);
1555
1556 if ((wpubl = wpabuf_alloc(prime_len)) && (wpriv = wpabuf_alloc(prime_len)) &&
1557 crypto_mbedtls_dh_init_public(ctx, generator, prime, prime_len, wpabuf_put(wpriv, prime_len),
1558 wpabuf_put(wpubl, prime_len)) == 0)
1559 {
1560 wpabuf_free(*publ);
1561 wpabuf_clear_free(*priv);
1562 *publ = wpubl;
1563 *priv = wpriv;
1564 return ctx;
1565 }
1566
1567 wpabuf_clear_free(wpriv);
1568 wpabuf_free(wpubl);
1569 mbedtls_dhm_free(ctx);
1570 os_free(ctx);
1571 return NULL;
1572 }
1573
1574 #ifdef CRYPTO_MBEDTLS_DH5_INIT_FIXED
dh5_init_fixed(const struct wpabuf * priv,const struct wpabuf * publ)1575 void *dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
1576 {
1577 const unsigned char *const prime = RFC3526_PRIME_1536;
1578 const size_t prime_len = sizeof(RFC3526_PRIME_1536);
1579 const u8 generator = *RFC3526_GENERATOR_1536;
1580
1581 mbedtls_dhm_context *ctx = os_malloc(sizeof(*ctx));
1582 if (ctx == NULL)
1583 return NULL;
1584 mbedtls_dhm_init(ctx);
1585
1586 if (crypto_mbedtls_dh_set_bin_pg(ctx, generator, prime, prime_len) == 0
1587 && mbedtls_mpi_read_binary(&ctx->MBEDTLS_PRIVATE(X), wpabuf_head(priv), wpabuf_len(priv)) == 0)
1588 {
1589 return ctx;
1590 }
1591
1592 mbedtls_dhm_free(ctx);
1593 os_free(ctx);
1594 return NULL;
1595 }
1596 #endif
1597
dh5_derive_shared(void * ctx,const struct wpabuf * peer_public,const struct wpabuf * own_private)1598 struct wpabuf *dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, const struct wpabuf *own_private)
1599 {
1600 /*((mbedtls_dhm_context *)ctx must already contain own_private)*/
1601 /* mbedtls 2.x: prime_len = ctx->len; */
1602 /* mbedtls 3.x: prime_len = mbedtls_dhm_get_len(ctx); */
1603 size_t olen = sizeof(RFC3526_PRIME_1536); /*(sizeof(); prime known)*/
1604 struct wpabuf *buf = wpabuf_alloc(olen);
1605 if (buf == NULL)
1606 return NULL;
1607 if (mbedtls_dhm_read_public((mbedtls_dhm_context *)ctx, wpabuf_head(peer_public), wpabuf_len(peer_public)) == 0 &&
1608 mbedtls_dhm_calc_secret(ctx, wpabuf_mhead(buf), olen, &olen, hostap_rng_fn, hostap_rng_ctx()) == 0)
1609 {
1610 wpabuf_put(buf, olen);
1611 return buf;
1612 }
1613
1614 wpabuf_free(buf);
1615 return NULL;
1616 }
1617
dh5_free(void * ctx)1618 void dh5_free(void *ctx)
1619 {
1620 mbedtls_dhm_free(ctx);
1621 os_free(ctx);
1622 }
1623
1624 #endif /* CRYPTO_MBEDTLS_CRYPTO_DH */
1625
1626 #if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC)
1627
1628 #include <mbedtls/ecp.h>
1629
1630 #define CRYPTO_EC_pbits(e) (((mbedtls_ecp_group *)(e))->pbits)
1631 #define CRYPTO_EC_plen(e) ((((mbedtls_ecp_group *)(e))->pbits + 7) >> 3)
1632 #define CRYPTO_EC_P(e) (&((mbedtls_ecp_group *)(e))->P)
1633 #define CRYPTO_EC_N(e) (&((mbedtls_ecp_group *)(e))->N)
1634 #define CRYPTO_EC_A(e) (&((mbedtls_ecp_group *)(e))->A)
1635 #define CRYPTO_EC_B(e) (&((mbedtls_ecp_group *)(e))->B)
1636 #define CRYPTO_EC_G(e) (&((mbedtls_ecp_group *)(e))->G)
1637
crypto_mbedtls_ecp_group_id_from_ike_id(int group)1638 static mbedtls_ecp_group_id crypto_mbedtls_ecp_group_id_from_ike_id(int group)
1639 {
1640 /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */
1641 switch (group)
1642 {
1643 #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
1644 case 19:
1645 return MBEDTLS_ECP_DP_SECP256R1;
1646 #endif
1647 #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
1648 case 20:
1649 return MBEDTLS_ECP_DP_SECP384R1;
1650 #endif
1651 #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
1652 case 21:
1653 return MBEDTLS_ECP_DP_SECP521R1;
1654 #endif
1655 #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED
1656 case 25:
1657 return MBEDTLS_ECP_DP_SECP192R1;
1658 #endif
1659 #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED
1660 case 26:
1661 return MBEDTLS_ECP_DP_SECP224R1;
1662 #endif
1663 #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED
1664 case 28:
1665 return MBEDTLS_ECP_DP_BP256R1;
1666 #endif
1667 #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED
1668 case 29:
1669 return MBEDTLS_ECP_DP_BP384R1;
1670 #endif
1671 #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED
1672 case 30:
1673 return MBEDTLS_ECP_DP_BP512R1;
1674 #endif
1675 #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
1676 case 31:
1677 return MBEDTLS_ECP_DP_CURVE25519;
1678 #endif
1679 #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
1680 case 32:
1681 return MBEDTLS_ECP_DP_CURVE448;
1682 #endif
1683 default:
1684 return MBEDTLS_ECP_DP_NONE;
1685 }
1686 }
1687
1688 #endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH || CRYPTO_MBEDTLS_CRYPTO_EC */
1689
1690 #ifdef CRYPTO_MBEDTLS_CRYPTO_EC
crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id)1691 static int crypto_mbedtls_ike_id_from_ecp_group_id(mbedtls_ecp_group_id grp_id)
1692 {
1693 /* https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml */
1694 /*(for crypto_ec_key_group())*/
1695 switch (grp_id)
1696 {
1697 #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
1698 case MBEDTLS_ECP_DP_SECP256R1:
1699 return 19;
1700 #endif
1701 #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
1702 case MBEDTLS_ECP_DP_SECP384R1:
1703 return 20;
1704 #endif
1705 #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
1706 case MBEDTLS_ECP_DP_SECP521R1:
1707 return 21;
1708 #endif
1709 #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED
1710 case MBEDTLS_ECP_DP_SECP192R1:
1711 return 25;
1712 #endif
1713 #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED
1714 case MBEDTLS_ECP_DP_SECP224R1:
1715 return 26;
1716 #endif
1717 #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED
1718 case MBEDTLS_ECP_DP_BP256R1:
1719 return 28;
1720 #endif
1721 #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED
1722 case MBEDTLS_ECP_DP_BP384R1:
1723 return 29;
1724 #endif
1725 #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED
1726 case MBEDTLS_ECP_DP_BP512R1:
1727 return 30;
1728 #endif
1729 #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
1730 case MBEDTLS_ECP_DP_CURVE25519:
1731 return 31;
1732 #endif
1733 #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
1734 case MBEDTLS_ECP_DP_CURVE448:
1735 return 32;
1736 #endif
1737 default:
1738 return -1;
1739 }
1740 }
1741
1742 #endif /* CRYPTO_MBEDTLS_CRYPTO_EC */
1743
1744 #if defined(CRYPTO_MBEDTLS_CRYPTO_ECDH) || defined(CRYPTO_MBEDTLS_CRYPTO_EC_DPP)
1745
1746 #include <mbedtls/ecp.h>
1747 #include <mbedtls/pk.h>
1748
crypto_mbedtls_keypair_gen(int group,mbedtls_pk_context * pk)1749 static int crypto_mbedtls_keypair_gen(int group, mbedtls_pk_context *pk)
1750 {
1751 mbedtls_ecp_group_id grp_id = crypto_mbedtls_ecp_group_id_from_ike_id(group);
1752 if (grp_id == MBEDTLS_ECP_DP_NONE)
1753 return -1;
1754 const mbedtls_pk_info_t *pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
1755 if (pk_info == NULL)
1756 return -1;
1757 return mbedtls_pk_setup(pk, pk_info) ||
1758 mbedtls_ecp_gen_key(grp_id, mbedtls_pk_ec(*pk), hostap_rng_fn, hostap_rng_ctx()) ?
1759 -1 :
1760 0;
1761 }
1762
1763 #endif
1764
1765 #ifdef CRYPTO_MBEDTLS_CRYPTO_ECDH
1766
1767 #include <mbedtls/ecdh.h>
1768 #include <mbedtls/ecdsa.h>
1769 #include <mbedtls/ecp.h>
1770 #include <mbedtls/pk.h>
1771
1772 /* wrap mbedtls_ecdh_context for more future-proof direct access to components
1773 * (mbedtls_ecdh_context internal implementation may change between releases)
1774 *
1775 * If mbedtls_pk_context -- specifically underlying mbedtls_ecp_keypair --
1776 * lifetime were guaranteed to be longer than that of mbedtls_ecdh_context,
1777 * then mbedtls_pk_context or mbedtls_ecp_keypair could be stored in crypto_ecdh
1778 * (or crypto_ec_key could be stored in crypto_ecdh, and crypto_ec_key could
1779 * wrap mbedtls_ecp_keypair and components, to avoid MBEDTLS_PRIVATE access) */
1780 struct crypto_ecdh
1781 {
1782 mbedtls_ecdh_context ctx;
1783 mbedtls_ecp_group grp;
1784 mbedtls_ecp_point Q;
1785 };
1786
1787 struct crypto_ec
1788 {
1789 mbedtls_ecp_group group;
1790 };
1791
crypto_ecdh_init(int group)1792 struct crypto_ecdh *crypto_ecdh_init(int group)
1793 {
1794 mbedtls_pk_context pk;
1795 mbedtls_pk_init(&pk);
1796 struct crypto_ecdh *ecdh =
1797 crypto_mbedtls_keypair_gen(group, &pk) == 0 ? crypto_ecdh_init2(group, (struct crypto_ec_key *)&pk) : NULL;
1798 mbedtls_pk_free(&pk);
1799 return ecdh;
1800 }
1801
crypto_ecdh_init2(int group,struct crypto_ec_key * own_key)1802 struct crypto_ecdh *crypto_ecdh_init2(int group, struct crypto_ec_key *own_key)
1803 {
1804 mbedtls_ecp_group_id grp_id = crypto_mbedtls_ecp_group_id_from_ike_id(group);
1805 if (grp_id == MBEDTLS_ECP_DP_NONE)
1806 return NULL;
1807 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)own_key);
1808 struct crypto_ecdh *ecdh = os_malloc(sizeof(*ecdh));
1809 if (ecdh == NULL)
1810 return NULL;
1811 mbedtls_ecdh_init(&ecdh->ctx);
1812 mbedtls_ecp_group_init(&ecdh->grp);
1813 mbedtls_ecp_point_init(&ecdh->Q);
1814 if (mbedtls_ecdh_setup(&ecdh->ctx, grp_id) == 0 &&
1815 mbedtls_ecdh_get_params(&ecdh->ctx, ecp_kp, MBEDTLS_ECDH_OURS) == 0)
1816 {
1817 /* copy grp and Q for later use
1818 * (retrieving this info later is more convoluted
1819 * even if mbedtls_ecdh_make_public() is considered)*/
1820 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */
1821 mbedtls_mpi d;
1822 mbedtls_mpi_init(&d);
1823 if (mbedtls_ecp_export(ecp_kp, &ecdh->grp, &d, &ecdh->Q) == 0)
1824 {
1825 mbedtls_mpi_free(&d);
1826 return ecdh;
1827 }
1828 mbedtls_mpi_free(&d);
1829 #else
1830 if (mbedtls_ecp_group_load(&ecdh->grp, grp_id) == 0 &&
1831 mbedtls_ecp_copy(&ecdh->Q, &ecp_kp->MBEDTLS_PRIVATE(Q)) == 0)
1832 return ecdh;
1833 #endif
1834 }
1835
1836 mbedtls_ecp_point_free(&ecdh->Q);
1837 mbedtls_ecp_group_free(&ecdh->grp);
1838 mbedtls_ecdh_free(&ecdh->ctx);
1839 os_free(ecdh);
1840 return NULL;
1841 }
1842
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)1843 struct wpabuf *crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
1844 {
1845 mbedtls_ecp_group *grp = &ecdh->grp;
1846 size_t len = CRYPTO_EC_plen(grp);
1847 #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
1848 /* len */
1849 #endif
1850 #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
1851 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS)
1852 len = inc_y ? len * 2 + 1 : len + 1;
1853 #endif
1854 struct wpabuf *buf = wpabuf_alloc(len);
1855 if (buf == NULL)
1856 return NULL;
1857 inc_y = inc_y ? MBEDTLS_ECP_PF_UNCOMPRESSED : MBEDTLS_ECP_PF_COMPRESSED;
1858 if (mbedtls_ecp_point_write_binary(grp, &ecdh->Q, inc_y, &len, wpabuf_mhead_u8(buf), len) == 0)
1859 {
1860 wpabuf_put(buf, len);
1861 return buf;
1862 }
1863
1864 wpabuf_free(buf);
1865 return NULL;
1866 }
1867
1868 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group * grp,mbedtls_mpi * bn,int parity_bit)1869 static int crypto_mbedtls_short_weierstrass_derive_y(mbedtls_ecp_group *grp, mbedtls_mpi *bn, int parity_bit)
1870 {
1871 /* y^2 = x^3 + ax + b
1872 * sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */
1873 mbedtls_mpi *cy2 =
1874 (mbedtls_mpi *)crypto_ec_point_compute_y_sqr((struct crypto_ec *)grp, (const struct crypto_bignum *)bn); /*x*/
1875 if (cy2 == NULL)
1876 return -1;
1877
1878 /*mbedtls_mpi_free(bn);*/
1879 /*(reuse bn to store result (y))*/
1880
1881 mbedtls_mpi exp;
1882 mbedtls_mpi_init(&exp);
1883 int ret = mbedtls_mpi_get_bit(&grp->P, 0) != 1 /*(p = 3 mod 4)*/
1884 || mbedtls_mpi_get_bit(&grp->P, 1) != 1 /*(p = 3 mod 4)*/
1885 || mbedtls_mpi_add_int(&exp, &grp->P, 1) || mbedtls_mpi_shift_r(&exp, 2) ||
1886 mbedtls_mpi_exp_mod(bn, cy2, &exp, &grp->P, NULL) ||
1887 (mbedtls_mpi_get_bit(bn, 0) != parity_bit && mbedtls_mpi_sub_mpi(bn, &grp->P, bn));
1888 mbedtls_mpi_free(&exp);
1889 mbedtls_mpi_free(cy2);
1890 os_free(cy2);
1891 return ret;
1892 }
1893 #endif
1894
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)1895 struct wpabuf *crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, const u8 *key, size_t len)
1896 {
1897 if (len == 0) /*(invalid peer key)*/
1898 return NULL;
1899
1900 mbedtls_ecp_group *grp = &ecdh->grp;
1901
1902 #if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
1903 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS)
1904 {
1905 /* add header for mbedtls_ecdh_read_public() */
1906 u8 buf[256];
1907 if (sizeof(buf) - 1 < len)
1908 return NULL;
1909 buf[0] = (u8)(len);
1910 os_memcpy(buf + 1, key, len);
1911
1912 if (inc_y)
1913 {
1914 if (!(len & 1))
1915 { /*(dpp code/tests does not include tag?!?)*/
1916 if (sizeof(buf) - 2 < len)
1917 return NULL;
1918 buf[0] = (u8)(1 + len);
1919 buf[1] = 0x04;
1920 os_memcpy(buf + 2, key, len);
1921 }
1922 len >>= 1; /*(repurpose len to prime_len)*/
1923 }
1924 else if (key[0] == 0x02 || key[0] == 0x03)
1925 { /* (inc_y == 0) */
1926 --len; /*(repurpose len to prime_len)*/
1927
1928 /* mbedtls_ecp_point_read_binary() does not currently support
1929 * MBEDTLS_ECP_PF_COMPRESSED format (buf[1] = 0x02 or 0x03)
1930 * (returns MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) */
1931
1932 /* derive y, amend buf[] with y for UNCOMPRESSED format */
1933 if (sizeof(buf) - 2 < len * 2 || len == 0)
1934 return NULL;
1935 buf[0] = (u8)(1 + len * 2);
1936 buf[1] = 0x04;
1937 mbedtls_mpi bn;
1938 mbedtls_mpi_init(&bn);
1939 int ret = mbedtls_mpi_read_binary(&bn, key + 1, len) ||
1940 crypto_mbedtls_short_weierstrass_derive_y(grp, &bn, key[0] & 1) ||
1941 mbedtls_mpi_write_binary(&bn, buf + 2 + len, len);
1942 mbedtls_mpi_free(&bn);
1943 if (ret != 0)
1944 return NULL;
1945 }
1946
1947 if (key[0] == 0) /*(repurpose len to prime_len)*/
1948 len = CRYPTO_EC_plen(grp);
1949
1950 if (mbedtls_ecdh_read_public(&ecdh->ctx, buf, buf[0] + 1))
1951 return NULL;
1952 }
1953 #endif
1954 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
1955 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY)
1956 {
1957 if (mbedtls_ecdh_read_public(&ecdh->ctx, key, len))
1958 return NULL;
1959 }
1960 #endif
1961
1962 struct wpabuf *buf = wpabuf_alloc(len);
1963 if (buf == NULL)
1964 return NULL;
1965
1966 if (mbedtls_ecdh_calc_secret(&ecdh->ctx, &len, wpabuf_mhead(buf), len, hostap_rng_fn, hostap_rng_ctx()) == 0)
1967 {
1968 wpabuf_put(buf, len);
1969 return buf;
1970 }
1971
1972 wpabuf_clear_free(buf);
1973 return NULL;
1974 }
1975
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)1976 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
1977 {
1978 if (ecdh == NULL)
1979 return;
1980 mbedtls_ecp_point_free(&ecdh->Q);
1981 mbedtls_ecp_group_free(&ecdh->grp);
1982 mbedtls_ecdh_free(&ecdh->ctx);
1983 os_free(ecdh);
1984 }
1985
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)1986 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
1987 {
1988 return CRYPTO_EC_plen(&ecdh->grp);
1989 }
1990
1991 #endif /* CRYPTO_MBEDTLS_CRYPTO_ECDH */
1992
1993 #if defined(CRYPTO_MBEDTLS_CRYPTO_EC)
1994
1995 #include <mbedtls/ecp.h>
1996
crypto_ec_init(int group)1997 struct crypto_ec *crypto_ec_init(int group)
1998 {
1999 mbedtls_ecp_group_id grp_id = crypto_mbedtls_ecp_group_id_from_ike_id(group);
2000 if (grp_id == MBEDTLS_ECP_DP_NONE)
2001 return NULL;
2002 mbedtls_ecp_group *e = os_malloc(sizeof(*e));
2003 if (e == NULL)
2004 return NULL;
2005 mbedtls_ecp_group_init(e);
2006 if (mbedtls_ecp_group_load(e, grp_id) == 0)
2007 return (struct crypto_ec *)e;
2008
2009 mbedtls_ecp_group_free(e);
2010 os_free(e);
2011 return NULL;
2012 }
2013
crypto_ec_deinit(struct crypto_ec * e)2014 void crypto_ec_deinit(struct crypto_ec *e)
2015 {
2016 mbedtls_ecp_group_free((mbedtls_ecp_group *)e);
2017 os_free(e);
2018 }
2019
crypto_ec_prime_len(struct crypto_ec * e)2020 size_t crypto_ec_prime_len(struct crypto_ec *e)
2021 {
2022 return CRYPTO_EC_plen(e);
2023 }
2024
crypto_ec_prime_len_bits(struct crypto_ec * e)2025 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
2026 {
2027 return CRYPTO_EC_pbits(e);
2028 }
2029
crypto_ec_order_len(struct crypto_ec * e)2030 size_t crypto_ec_order_len(struct crypto_ec *e)
2031 {
2032 return (mbedtls_mpi_bitlen(CRYPTO_EC_N(e)) + 7) / 8;
2033 }
2034
crypto_ec_get_prime(struct crypto_ec * e)2035 const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e)
2036 {
2037 return (const struct crypto_bignum *)CRYPTO_EC_P(e);
2038 }
2039
crypto_ec_get_order(struct crypto_ec * e)2040 const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e)
2041 {
2042 return (const struct crypto_bignum *)CRYPTO_EC_N(e);
2043 }
2044
crypto_ec_get_a(struct crypto_ec * e)2045 const struct crypto_bignum *crypto_ec_get_a(struct crypto_ec *e)
2046 {
2047 #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
2048 static const uint8_t secp256r1_a[] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2049 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
2050 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc};
2051 #endif
2052 #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
2053 static const uint8_t secp384r1_a[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2054 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2055 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
2056 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc};
2057 #endif
2058 #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
2059 static const uint8_t secp521r1_a[] = {
2060 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2061 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2062 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2063 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc};
2064 #endif
2065 #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED
2066 static const uint8_t secp192r1_a[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2067 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc};
2068 #endif
2069 #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED
2070 static const uint8_t secp224r1_a[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2071 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
2072 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe};
2073 #endif
2074
2075 const uint8_t *bin = NULL;
2076 size_t len = 0;
2077
2078 /* (mbedtls groups matching supported sswu_curve_param() IKE groups) */
2079 switch (((mbedtls_ecp_group *)e)->id)
2080 {
2081 #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
2082 case MBEDTLS_ECP_DP_SECP256R1:
2083 bin = secp256r1_a;
2084 len = sizeof(secp256r1_a);
2085 break;
2086 #endif
2087 #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
2088 case MBEDTLS_ECP_DP_SECP384R1:
2089 bin = secp384r1_a;
2090 len = sizeof(secp384r1_a);
2091 break;
2092 #endif
2093 #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
2094 case MBEDTLS_ECP_DP_SECP521R1:
2095 bin = secp521r1_a;
2096 len = sizeof(secp521r1_a);
2097 break;
2098 #endif
2099 #ifdef MBEDTLS_ECP_DP_SECP192R1_ENABLED
2100 case MBEDTLS_ECP_DP_SECP192R1:
2101 bin = secp192r1_a;
2102 len = sizeof(secp192r1_a);
2103 break;
2104 #endif
2105 #ifdef MBEDTLS_ECP_DP_SECP224R1_ENABLED
2106 case MBEDTLS_ECP_DP_SECP224R1:
2107 bin = secp224r1_a;
2108 len = sizeof(secp224r1_a);
2109 break;
2110 #endif
2111 #ifdef MBEDTLS_ECP_DP_BP256R1_ENABLED
2112 case MBEDTLS_ECP_DP_BP256R1:
2113 return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2114 #endif
2115 #ifdef MBEDTLS_ECP_DP_BP384R1_ENABLED
2116 case MBEDTLS_ECP_DP_BP384R1:
2117 return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2118 #endif
2119 #ifdef MBEDTLS_ECP_DP_BP512R1_ENABLED
2120 case MBEDTLS_ECP_DP_BP512R1:
2121 return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2122 #endif
2123 #ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
2124 case MBEDTLS_ECP_DP_CURVE25519:
2125 return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2126 #endif
2127 #ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
2128 case MBEDTLS_ECP_DP_CURVE448:
2129 return (const struct crypto_bignum *)CRYPTO_EC_A(e);
2130 #endif
2131 default:
2132 return NULL;
2133 }
2134
2135 /*(note: not thread-safe; returns file-scoped static storage)*/
2136 if (mbedtls_mpi_read_binary(&mpi_sw_A, bin, len) == 0)
2137 return (const struct crypto_bignum *)&mpi_sw_A;
2138 return NULL;
2139 }
2140
crypto_ec_get_b(struct crypto_ec * e)2141 const struct crypto_bignum *crypto_ec_get_b(struct crypto_ec *e)
2142 {
2143 return (const struct crypto_bignum *)CRYPTO_EC_B(e);
2144 }
2145
crypto_ec_get_generator(struct crypto_ec * e)2146 const struct crypto_ec_point *crypto_ec_get_generator(struct crypto_ec *e)
2147 {
2148 return (const struct crypto_ec_point *)CRYPTO_EC_G(e);
2149 }
2150
crypto_ec_point_init(struct crypto_ec * e)2151 struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e)
2152 {
2153 if (TEST_FAIL())
2154 return NULL;
2155
2156 mbedtls_ecp_point *p = os_malloc(sizeof(*p));
2157 if (p != NULL)
2158 mbedtls_ecp_point_init(p);
2159 return (struct crypto_ec_point *)p;
2160 }
2161
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)2162 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
2163 {
2164 mbedtls_ecp_point_free((mbedtls_ecp_point *)p);
2165 os_free(p);
2166 }
2167
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)2168 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p, struct crypto_bignum *x)
2169 {
2170 mbedtls_mpi *px = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X);
2171 return mbedtls_mpi_copy((mbedtls_mpi *)x, px) ? -1 : 0;
2172 }
2173
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)2174 int crypto_ec_point_to_bin(struct crypto_ec *e, const struct crypto_ec_point *point, u8 *x, u8 *y)
2175 {
2176 if (TEST_FAIL())
2177 return -1;
2178
2179 /* crypto.h documents crypto_ec_point_to_bin() output is big-endian */
2180 size_t len = CRYPTO_EC_plen(e);
2181 if (x)
2182 {
2183 mbedtls_mpi *px = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(X);
2184 if (mbedtls_mpi_write_binary(px, x, len))
2185 return -1;
2186 }
2187 if (y)
2188 {
2189 mbedtls_mpi *py = &((mbedtls_ecp_point *)point)->MBEDTLS_PRIVATE(Y);
2190 if (mbedtls_mpi_write_binary(py, y, len))
2191 return -1;
2192 }
2193 return 0;
2194 }
2195
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)2196 struct crypto_ec_point *crypto_ec_point_from_bin(struct crypto_ec *e, const u8 *val)
2197 {
2198 if (TEST_FAIL())
2199 return NULL;
2200
2201 size_t len = CRYPTO_EC_plen(e);
2202 mbedtls_ecp_point *p = os_malloc(sizeof(*p));
2203 u8 buf[1 + MBEDTLS_MPI_MAX_SIZE * 2];
2204 if (p == NULL)
2205 return NULL;
2206 mbedtls_ecp_point_init(p);
2207
2208 #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
2209 if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS)
2210 {
2211 buf[0] = 0x04;
2212 os_memcpy(buf + 1, val, len * 2);
2213 if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, buf, 1 + len * 2) == 0)
2214 return (struct crypto_ec_point *)p;
2215 }
2216 #endif
2217 #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
2218 if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) == MBEDTLS_ECP_TYPE_MONTGOMERY)
2219 {
2220 /* crypto.h interface documents crypto_ec_point_from_bin()
2221 * val is length: prime_len * 2 and is big-endian
2222 * (Short Weierstrass is assumed by hostap)
2223 * Reverse to little-endian format for Montgomery */
2224 for (unsigned int i = 0; i < len; ++i)
2225 buf[i] = val[len - 1 - i];
2226 if (mbedtls_ecp_point_read_binary((mbedtls_ecp_group *)e, p, buf, len) == 0)
2227 return (struct crypto_ec_point *)p;
2228 }
2229 #endif
2230
2231 mbedtls_ecp_point_free(p);
2232 os_free(p);
2233 return NULL;
2234 }
2235
crypto_ec_point_add(struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b,struct crypto_ec_point * c)2236 int crypto_ec_point_add(struct crypto_ec *e,
2237 const struct crypto_ec_point *a,
2238 const struct crypto_ec_point *b,
2239 struct crypto_ec_point *c)
2240 {
2241 if (TEST_FAIL())
2242 return -1;
2243
2244 /* mbedtls does not provide an mbedtls_ecp_point add function */
2245 mbedtls_mpi one;
2246 mbedtls_mpi_init(&one);
2247 int ret = mbedtls_mpi_lset(&one, 1) ||
2248 mbedtls_ecp_muladd((mbedtls_ecp_group *)e, (mbedtls_ecp_point *)c, &one,
2249 (const mbedtls_ecp_point *)a, &one, (const mbedtls_ecp_point *)b) ?
2250 -1 :
2251 0;
2252 mbedtls_mpi_free(&one);
2253 return ret;
2254 }
2255
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)2256 int crypto_ec_point_mul(struct crypto_ec *e,
2257 const struct crypto_ec_point *p,
2258 const struct crypto_bignum *b,
2259 struct crypto_ec_point *res)
2260 {
2261 if (TEST_FAIL())
2262 return -1;
2263
2264 return mbedtls_ecp_mul((mbedtls_ecp_group *)e, (mbedtls_ecp_point *)res, (const mbedtls_mpi *)b,
2265 (const mbedtls_ecp_point *)p, hostap_rng_fn, hostap_rng_ctx()) ?
2266 -1 :
2267 0;
2268 }
2269
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)2270 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
2271 {
2272 if (TEST_FAIL())
2273 return -1;
2274
2275 if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) == MBEDTLS_ECP_TYPE_MONTGOMERY)
2276 {
2277 /* e.g. MBEDTLS_ECP_DP_CURVE25519 and MBEDTLS_ECP_DP_CURVE448 */
2278 wpa_printf(MSG_ERROR, "%s not implemented for Montgomery curves", __func__);
2279 return -1;
2280 }
2281
2282 /* mbedtls does not provide an mbedtls_ecp_point invert function */
2283 /* below works for Short Weierstrass; incorrect for Montgomery curves */
2284 mbedtls_mpi *py = &((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y);
2285 return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p) /*point at infinity*/
2286 || mbedtls_mpi_cmp_int(py, 0) == 0 /*point is its own inverse*/
2287 || mbedtls_mpi_sub_abs(py, CRYPTO_EC_P(e), py) == 0 ?
2288 0 :
2289 -1;
2290 }
2291
2292 #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
crypto_ec_point_y_sqr_weierstrass(mbedtls_ecp_group * e,const mbedtls_mpi * x,mbedtls_mpi * y2)2293 static int crypto_ec_point_y_sqr_weierstrass(mbedtls_ecp_group *e, const mbedtls_mpi *x, mbedtls_mpi *y2)
2294 {
2295 /* MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS y^2 = x^3 + a x + b */
2296
2297 /* Short Weierstrass elliptic curve group w/o A set treated as A = -3 */
2298 /* Attempt to match mbedtls/library/ecp.c:ecp_check_pubkey_sw() behavior
2299 * and elsewhere in mbedtls/library/ecp.c where if A is not set, it is
2300 * treated as if A = -3. */
2301
2302 /* y^2 = x^3 + ax + b = (x^2 + a)x + b */
2303 return /* x^2 */
2304 mbedtls_mpi_mul_mpi(y2, x, x) ||
2305 mbedtls_mpi_mod_mpi(y2, y2, &e->P)
2306 /* x^2 + a */
2307 || (e->A.MBEDTLS_PRIVATE(p) ? mbedtls_mpi_add_mpi(y2, y2, &e->A) : mbedtls_mpi_sub_int(y2, y2, 3)) ||
2308 mbedtls_mpi_mod_mpi(y2, y2, &e->P)
2309 /* (x^2 + a)x */
2310 || mbedtls_mpi_mul_mpi(y2, y2, x) ||
2311 mbedtls_mpi_mod_mpi(y2, y2, &e->P)
2312 /* (x^2 + a)x + b */
2313 || mbedtls_mpi_add_mpi(y2, y2, &e->B) || mbedtls_mpi_mod_mpi(y2, y2, &e->P);
2314 }
2315 #endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
2316
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)2317 struct crypto_bignum *crypto_ec_point_compute_y_sqr(struct crypto_ec *e, const struct crypto_bignum *x)
2318 {
2319 if (TEST_FAIL())
2320 return NULL;
2321
2322 mbedtls_mpi *y2 = os_malloc(sizeof(*y2));
2323 if (y2 == NULL)
2324 return NULL;
2325 mbedtls_mpi_init(y2);
2326
2327 #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
2328 if (mbedtls_ecp_get_type((mbedtls_ecp_group *)e) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS &&
2329 crypto_ec_point_y_sqr_weierstrass((mbedtls_ecp_group *)e, (const mbedtls_mpi *)x, y2) == 0)
2330 return (struct crypto_bignum *)y2;
2331 #endif
2332
2333 mbedtls_mpi_free(y2);
2334 os_free(y2);
2335 return NULL;
2336 }
2337
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)2338 int crypto_ec_point_is_at_infinity(struct crypto_ec *e, const struct crypto_ec_point *p)
2339 {
2340 return mbedtls_ecp_is_zero((mbedtls_ecp_point *)p);
2341 }
2342
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)2343 int crypto_ec_point_is_on_curve(struct crypto_ec *e, const struct crypto_ec_point *p)
2344 {
2345 return mbedtls_ecp_check_pubkey((const mbedtls_ecp_group *)e, (const mbedtls_ecp_point *)p) == 0;
2346 }
2347
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)2348 int crypto_ec_point_cmp(const struct crypto_ec *e, const struct crypto_ec_point *a, const struct crypto_ec_point *b)
2349 {
2350 return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *)a, (const mbedtls_ecp_point *)b);
2351 }
2352
2353 #if !defined(CONFIG_NO_STDOUT_DEBUG)
crypto_ec_point_debug_print(const struct crypto_ec * e,const struct crypto_ec_point * p,const char * title)2354 void crypto_ec_point_debug_print(const struct crypto_ec *e, const struct crypto_ec_point *p, const char *title)
2355 {
2356 u8 x[MBEDTLS_MPI_MAX_SIZE];
2357 u8 y[MBEDTLS_MPI_MAX_SIZE];
2358 size_t len = CRYPTO_EC_plen(e);
2359 /* crypto_ec_point_to_bin ought to take (const struct crypto_ec *e) */
2360 struct crypto_ec *ee;
2361 *(const struct crypto_ec **)&ee = e; /*(cast away const)*/
2362 if (crypto_ec_point_to_bin(ee, p, x, y) == 0)
2363 {
2364 if (title)
2365 wpa_printf(MSG_DEBUG, "%s", title);
2366 wpa_hexdump(MSG_DEBUG, "x:", x, len);
2367 wpa_hexdump(MSG_DEBUG, "y:", y, len);
2368 }
2369 }
2370 #else
crypto_ec_point_debug_print(const struct crypto_ec * e,const struct crypto_ec_point * p,const char * title)2371 void crypto_ec_point_debug_print(const struct crypto_ec *e, const struct crypto_ec_point *p, const char *title)
2372 {
2373 // Fixing linking error undefined reference to `crypto_ec_point_debug_print'
2374 }
2375 #endif
2376
crypto_ec_key_parse_priv(const u8 * der,size_t der_len)2377 struct crypto_ec_key *crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
2378 {
2379 mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
2380 if (ctx == NULL)
2381 return NULL;
2382 mbedtls_pk_init(ctx);
2383 #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
2384 if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0) == 0)
2385 #else
2386 if (mbedtls_pk_parse_key(ctx, der, der_len, NULL, 0, hostap_rng_fn, hostap_rng_ctx()) == 0)
2387 #endif
2388 return (struct crypto_ec_key *)ctx;
2389
2390 mbedtls_pk_free(ctx);
2391 os_free(ctx);
2392 return NULL;
2393 }
2394
2395 #include <mbedtls/error.h>
2396 #include <mbedtls/oid.h>
crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context * ctx,const u8 * der,size_t der_len)2397 static int crypto_mbedtls_pk_parse_subpubkey_compressed(mbedtls_pk_context *ctx, const u8 *der, size_t der_len)
2398 {
2399 /* The following is modified from:
2400 * mbedtls/library/pkparse.c:mbedtls_pk_parse_subpubkey()
2401 * mbedtls/library/pkparse.c:pk_get_pk_alg()
2402 * mbedtls/library/pkparse.c:pk_use_ecparams()
2403 */
2404 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
2405 const mbedtls_pk_info_t *pk_info;
2406 int ret;
2407 size_t len;
2408 const unsigned char *end = der + der_len;
2409 unsigned char *p;
2410 *(const unsigned char **)&p = der;
2411
2412 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0)
2413 {
2414 return (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret));
2415 }
2416
2417 end = p + len;
2418
2419 /*
2420 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &alg_params ) ) != 0 )
2421 return( ret );
2422 */
2423 mbedtls_asn1_buf alg_oid, params;
2424 memset(¶ms, 0, sizeof(mbedtls_asn1_buf));
2425 if ((ret = mbedtls_asn1_get_alg(&p, end, &alg_oid, ¶ms)) != 0)
2426 return (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_ALG, ret));
2427 if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0)
2428 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG);
2429
2430 if ((ret = mbedtls_asn1_get_bitstring_null(&p, end, &len)) != 0)
2431 return (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret));
2432
2433 if (p + len != end)
2434 return (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, MBEDTLS_ERR_ASN1_LENGTH_MISMATCH));
2435
2436 if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL)
2437 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG);
2438
2439 if ((ret = mbedtls_pk_setup(ctx, pk_info)) != 0)
2440 return (ret);
2441
2442 /* assume mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx)
2443 * has already run with ctx initialized up to pk_get_ecpubkey(),
2444 * and pk_get_ecpubkey() has returned MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
2445 *
2446 * mbedtls mbedtls_ecp_point_read_binary()
2447 * does not handle point in COMPRESSED format
2448 *
2449 * (validate assumption that algorithm is EC) */
2450 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx);
2451 if (ecp_kp == NULL)
2452 return (MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE);
2453 mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
2454 mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
2455 mbedtls_ecp_group_id grp_id;
2456
2457 /* mbedtls/library/pkparse.c:pk_use_ecparams() */
2458
2459 if (params.tag == MBEDTLS_ASN1_OID)
2460 {
2461 if (mbedtls_oid_get_ec_grp(¶ms, &grp_id) != 0)
2462 return (MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE);
2463 }
2464 else
2465 {
2466 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT);
2467 }
2468
2469 /*
2470 * grp may already be initialized; if so, make sure IDs match
2471 */
2472 if (ecp_kp_grp->id != MBEDTLS_ECP_DP_NONE && ecp_kp_grp->id != grp_id)
2473 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT);
2474
2475 if ((ret = mbedtls_ecp_group_load(ecp_kp_grp, grp_id)) != 0)
2476 return (ret);
2477
2478 /* (validate assumption that EC point is in COMPRESSED format) */
2479 len = CRYPTO_EC_plen(ecp_kp_grp);
2480 if (mbedtls_ecp_get_type(ecp_kp_grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS || (end - p) != 1 + len ||
2481 (*p != 0x02 && *p != 0x03))
2482 return (MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE);
2483
2484 /* Instead of calling mbedtls/library/pkparse.c:pk_get_ecpubkey() to call
2485 * mbedtls_ecp_point_read_binary(), manually parse point into ecp_kp_Q */
2486 mbedtls_mpi *X = &ecp_kp_Q->MBEDTLS_PRIVATE(X);
2487 mbedtls_mpi *Y = &ecp_kp_Q->MBEDTLS_PRIVATE(Y);
2488 mbedtls_mpi *Z = &ecp_kp_Q->MBEDTLS_PRIVATE(Z);
2489 ret = mbedtls_mpi_lset(Z, 1);
2490 if (ret != 0)
2491 return (ret);
2492 ret = mbedtls_mpi_read_binary(X, p + 1, len);
2493 if (ret != 0)
2494 return (ret);
2495 /* derive Y
2496 * (similar derivation of Y in crypto_mbedtls.c:crypto_ecdh_set_peerkey())*/
2497 ret = mbedtls_mpi_copy(Y, X) /*(Y is used as input and output obj below)*/
2498 || crypto_mbedtls_short_weierstrass_derive_y(ecp_kp_grp, Y, (*p & 1));
2499 if (ret != 0)
2500 return (ret);
2501
2502 return mbedtls_ecp_check_pubkey(ecp_kp_grp, ecp_kp_Q);
2503 }
2504
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)2505 struct crypto_ec_key *crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
2506 {
2507 mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
2508 if (ctx == NULL)
2509 return NULL;
2510 mbedtls_pk_init(ctx);
2511 /*int rc = mbedtls_pk_parse_subpubkey(&der, der+der_len, ctx);*/
2512 int rc = mbedtls_pk_parse_public_key(ctx, der, der_len);
2513 if (rc == 0)
2514 return (struct crypto_ec_key *)ctx;
2515 else if (rc == MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE)
2516 {
2517 /* mbedtls mbedtls_ecp_point_read_binary()
2518 * does not handle point in COMPRESSED format; parse internally */
2519 rc = crypto_mbedtls_pk_parse_subpubkey_compressed(ctx, der, der_len);
2520 if (rc == 0)
2521 return (struct crypto_ec_key *)ctx;
2522 }
2523
2524 mbedtls_pk_free(ctx);
2525 os_free(ctx);
2526 return NULL;
2527 }
2528
2529 #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id,const mbedtls_ecp_point * pub,const u8 * buf,size_t len)2530 static struct crypto_ec_key *crypto_ec_key_set_pub_point_for_group(mbedtls_ecp_group_id grp_id,
2531 const mbedtls_ecp_point *pub,
2532 const u8 *buf,
2533 size_t len)
2534 {
2535 const mbedtls_pk_info_t *pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
2536 if (pk_info == NULL)
2537 return NULL;
2538 mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
2539 if (ctx == NULL)
2540 return NULL;
2541 mbedtls_pk_init(ctx);
2542 if (mbedtls_pk_setup(ctx, pk_info) == 0)
2543 {
2544 /* (Is private key generation necessary for callers?)
2545 * alt: gen key then overwrite Q
2546 * mbedtls_ecp_gen_key(grp_id, ecp_kp, hostap_rng_fn, hostap_rng_ctx()) == 0
2547 */
2548 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*ctx);
2549 mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
2550 mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
2551 mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d);
2552 if (mbedtls_ecp_group_load(ecp_kp_grp, grp_id) == 0 &&
2553 (pub ? mbedtls_ecp_copy(ecp_kp_Q, pub) == 0 :
2554 mbedtls_ecp_point_read_binary(ecp_kp_grp, ecp_kp_Q, buf, len) == 0) &&
2555 mbedtls_ecp_gen_privkey(ecp_kp_grp, ecp_kp_d, hostap_rng_fn, hostap_rng_ctx()) == 0)
2556 {
2557 return (struct crypto_ec_key *)ctx;
2558 }
2559 }
2560
2561 mbedtls_pk_free(ctx);
2562 os_free(ctx);
2563 return NULL;
2564 }
2565
crypto_ec_key_set_pub(int group,const u8 * x,const u8 * y,size_t len)2566 struct crypto_ec_key *crypto_ec_key_set_pub(int group, const u8 *x, const u8 *y, size_t len)
2567 {
2568 mbedtls_ecp_group_id grp_id = crypto_mbedtls_ecp_group_id_from_ike_id(group);
2569 if (grp_id == MBEDTLS_ECP_DP_NONE)
2570 return NULL;
2571 if (len > MBEDTLS_MPI_MAX_SIZE)
2572 return NULL;
2573 u8 buf[1 + MBEDTLS_MPI_MAX_SIZE * 2];
2574 buf[0] = 0x04; /* assume x,y for Short Weierstrass */
2575 os_memcpy(buf + 1, x, len);
2576 os_memcpy(buf + 1 + len, y, len);
2577
2578 return crypto_ec_key_set_pub_point_for_group(grp_id, NULL, buf, 1 + len * 2);
2579 }
2580
crypto_ec_key_set_pub_point(struct crypto_ec * e,const struct crypto_ec_point * pub)2581 struct crypto_ec_key *crypto_ec_key_set_pub_point(struct crypto_ec *e, const struct crypto_ec_point *pub)
2582 {
2583 mbedtls_ecp_group_id grp_id = ((mbedtls_ecp_group *)e)->id;
2584 mbedtls_ecp_point *p = (mbedtls_ecp_point *)pub;
2585 return crypto_ec_key_set_pub_point_for_group(grp_id, p, NULL, 0);
2586 }
2587
crypto_ec_key_gen(int group)2588 struct crypto_ec_key *crypto_ec_key_gen(int group)
2589 {
2590 mbedtls_pk_context *ctx = os_malloc(sizeof(*ctx));
2591 if (ctx == NULL)
2592 return NULL;
2593 mbedtls_pk_init(ctx);
2594 if (crypto_mbedtls_keypair_gen(group, ctx) == 0)
2595 return (struct crypto_ec_key *)ctx;
2596 mbedtls_pk_free(ctx);
2597 os_free(ctx);
2598 return NULL;
2599 }
2600
2601 #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
2602
crypto_ec_key_deinit(struct crypto_ec_key * key)2603 void crypto_ec_key_deinit(struct crypto_ec_key *key)
2604 {
2605 mbedtls_pk_free((mbedtls_pk_context *)key);
2606 os_free(key);
2607 }
2608
crypto_ec_key_get_subject_public_key(struct crypto_ec_key * key)2609 struct wpabuf *crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
2610 {
2611 /* (similar to crypto_ec_key_get_pubkey_point(),
2612 * but compressed point format and ASN.1 DER wrapping)*/
2613 #ifndef MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/
2614 #define MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES)
2615 #endif
2616 unsigned char buf[MBEDTLS_PK_ECP_PUB_DER_MAX_BYTES];
2617 int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, buf, sizeof(buf));
2618 if (len < 0)
2619 return NULL;
2620 /* Note: data is written at the end of the buffer! Use the
2621 * return value to determine where you should start
2622 * using the buffer */
2623 unsigned char *p = buf + sizeof(buf) - len;
2624
2625 #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
2626 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
2627 if (ecp_kp == NULL)
2628 return NULL;
2629 mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
2630 /* Note: sae_pk.c expects pubkey point in compressed format,
2631 * but mbedtls_pk_write_pubkey_der() writes uncompressed format.
2632 * Manually translate format and update lengths in DER format */
2633 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS)
2634 {
2635 unsigned char *end = buf + sizeof(buf);
2636 size_t n;
2637 /* SubjectPublicKeyInfo SEQUENCE */
2638 mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2639 /* algorithm AlgorithmIdentifier */
2640 unsigned char *a = p;
2641 size_t alen;
2642 mbedtls_asn1_get_tag(&p, end, &alen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2643 p += alen;
2644 alen = (size_t)(p - a);
2645 /* subjectPublicKey BIT STRING */
2646 mbedtls_asn1_get_tag(&p, end, &n, MBEDTLS_ASN1_BIT_STRING);
2647 /* rewrite into compressed point format and rebuild ASN.1 */
2648 p[1] = (buf[sizeof(buf) - 1] & 1) ? 0x03 : 0x02;
2649 n = 1 + 1 + (n - 2) / 2;
2650 len = mbedtls_asn1_write_len(&p, buf, n) + (int)n;
2651 len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_BIT_STRING);
2652 os_memmove(p - alen, a, alen);
2653 len += alen;
2654 p -= alen;
2655 len += mbedtls_asn1_write_len(&p, buf, (size_t)len);
2656 len += mbedtls_asn1_write_tag(&p, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2657 }
2658 #endif
2659 return wpabuf_alloc_copy(p, (size_t)len);
2660 }
2661
2662 #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
crypto_ec_key_get_ecprivate_key(struct crypto_ec_key * key,bool include_pub)2663 struct wpabuf *crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, bool include_pub)
2664 {
2665 #ifndef MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES /*(mbedtls/library/pkwrite.h)*/
2666 #define MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES (29 + 3 * MBEDTLS_ECP_MAX_BYTES)
2667 #endif
2668 unsigned char priv[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES];
2669 int privlen = mbedtls_pk_write_key_der((mbedtls_pk_context *)key, priv, sizeof(priv));
2670 if (privlen < 0)
2671 return NULL;
2672
2673 struct wpabuf *wbuf;
2674
2675 /* Note: data is written at the end of the buffer! Use the
2676 * return value to determine where you should start
2677 * using the buffer */
2678 /* mbedtls_pk_write_key_der() includes publicKey in DER */
2679 if (include_pub)
2680 wbuf = wpabuf_alloc_copy(priv + sizeof(priv) - privlen, privlen);
2681 else
2682 {
2683 /* calculate publicKey offset and skip from end of buffer */
2684 unsigned char *p = priv + sizeof(priv) - privlen;
2685 unsigned char *end = priv + sizeof(priv);
2686 size_t len;
2687 /* ECPrivateKey SEQUENCE */
2688 mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2689 /* version INTEGER */
2690 unsigned char *v = p;
2691 mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
2692 p += len;
2693 /* privateKey OCTET STRING */
2694 mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
2695 p += len;
2696 /* parameters ECParameters */
2697 mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED);
2698 p += len;
2699
2700 /* write new SEQUENCE header (we know that it fits in priv[]) */
2701 len = (size_t)(p - v);
2702 p = v;
2703 len += mbedtls_asn1_write_len(&p, priv, len);
2704 len += mbedtls_asn1_write_tag(&p, priv, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2705 wbuf = wpabuf_alloc_copy(p, len);
2706 }
2707
2708 forced_memzero(priv, sizeof(priv));
2709 return wbuf;
2710 }
2711
crypto_ec_key_get_pubkey_point(struct crypto_ec_key * key,int prefix)2712 struct wpabuf *crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, int prefix)
2713 {
2714 /*(similarities to crypto_ecdh_get_pubkey(), but different struct)*/
2715 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
2716 if (ecp_kp == NULL)
2717 return NULL;
2718 mbedtls_ecp_group *grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
2719 size_t len = CRYPTO_EC_plen(grp);
2720 #ifdef MBEDTLS_ECP_MONTGOMERY_ENABLED
2721 /* len */
2722 #endif
2723 #ifdef MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
2724 if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS)
2725 len = len * 2 + 1;
2726 #endif
2727 struct wpabuf *buf = wpabuf_alloc(len);
2728 if (buf == NULL)
2729 return NULL;
2730 mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
2731 if (mbedtls_ecp_point_write_binary(grp, ecp_kp_Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &len, wpabuf_mhead_u8(buf), len) ==
2732 0)
2733 {
2734 if (!prefix) /* Remove 0x04 prefix if requested */
2735 os_memmove(wpabuf_mhead(buf), ((u8 *)wpabuf_mhead(buf) + 1), --len);
2736 wpabuf_put(buf, len);
2737 return buf;
2738 }
2739
2740 wpabuf_free(buf);
2741 return NULL;
2742 }
2743
crypto_ec_key_get_public_key(struct crypto_ec_key * key)2744 struct crypto_ec_point *crypto_ec_key_get_public_key(struct crypto_ec_key *key)
2745 {
2746 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
2747 if (ecp_kp == NULL)
2748 return NULL;
2749 mbedtls_ecp_point *p = os_malloc(sizeof(*p));
2750 if (p != NULL)
2751 {
2752 /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/
2753 mbedtls_ecp_point_init(p);
2754 mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
2755 if (mbedtls_ecp_copy(p, ecp_kp_Q))
2756 {
2757 mbedtls_ecp_point_free(p);
2758 os_free(p);
2759 p = NULL;
2760 }
2761 }
2762 return (struct crypto_ec_point *)p;
2763 }
2764
crypto_ec_key_get_private_key(struct crypto_ec_key * key)2765 struct crypto_bignum *crypto_ec_key_get_private_key(struct crypto_ec_key *key)
2766 {
2767 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
2768 if (ecp_kp == NULL)
2769 return NULL;
2770 mbedtls_mpi *bn = os_malloc(sizeof(*bn));
2771 if (bn)
2772 {
2773 /*(mbedtls_ecp_export() uses &ecp_kp->MBEDTLS_PRIVATE(grp))*/
2774 mbedtls_mpi_init(bn);
2775 mbedtls_mpi *ecp_kp_d = &ecp_kp->MBEDTLS_PRIVATE(d);
2776 if (mbedtls_mpi_copy(bn, ecp_kp_d))
2777 {
2778 mbedtls_mpi_free(bn);
2779 os_free(bn);
2780 bn = NULL;
2781 }
2782 }
2783 return (struct crypto_bignum *)bn;
2784 }
2785
2786 #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
2787
crypto_ec_key_sign_md(size_t len)2788 static mbedtls_md_type_t crypto_ec_key_sign_md(size_t len)
2789 {
2790 /* get mbedtls_md_type_t from length of hash data to be signed */
2791 switch (len)
2792 {
2793 case 64:
2794 return MBEDTLS_MD_SHA512;
2795 case 48:
2796 return MBEDTLS_MD_SHA384;
2797 case 32:
2798 return MBEDTLS_MD_SHA256;
2799 case 20:
2800 return MBEDTLS_MD_SHA1;
2801 case 16:
2802 return MBEDTLS_MD_MD5;
2803 default:
2804 return MBEDTLS_MD_NONE;
2805 }
2806 }
2807
crypto_ec_key_sign(struct crypto_ec_key * key,const u8 * data,size_t len)2808 struct wpabuf *crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, size_t len)
2809 {
2810 #ifndef MBEDTLS_PK_SIGNATURE_MAX_SIZE /*(defined since mbedtls 2.20.0)*/
2811 #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
2812 #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
2813 #else
2814 #define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
2815 #endif
2816 #endif
2817 size_t sig_len = MBEDTLS_PK_SIGNATURE_MAX_SIZE;
2818 struct wpabuf *buf = wpabuf_alloc(sig_len);
2819 if (buf == NULL)
2820 return NULL;
2821 if (mbedtls_pk_sign((mbedtls_pk_context *)key, crypto_ec_key_sign_md(len), data, len, wpabuf_mhead_u8(buf),
2822 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
2823 sig_len,
2824 #endif
2825 &sig_len, hostap_rng_fn, hostap_rng_ctx()) == 0)
2826 {
2827 wpabuf_put(buf, sig_len);
2828 return buf;
2829 }
2830
2831 wpabuf_free(buf);
2832 return NULL;
2833 }
2834
2835 #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
crypto_ec_key_sign_r_s(struct crypto_ec_key * key,const u8 * data,size_t len)2836 struct wpabuf *crypto_ec_key_sign_r_s(struct crypto_ec_key *key, const u8 *data, size_t len)
2837 {
2838 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
2839 if (ecp_kp == NULL)
2840 return NULL;
2841
2842 size_t sig_len = MBEDTLS_ECDSA_MAX_LEN;
2843 u8 buf[MBEDTLS_ECDSA_MAX_LEN];
2844 if (mbedtls_ecdsa_write_signature(ecp_kp, crypto_ec_key_sign_md(len), data, len, buf,
2845 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
2846 sig_len,
2847 #endif
2848 &sig_len, hostap_rng_fn, hostap_rng_ctx()))
2849 {
2850 return NULL;
2851 }
2852
2853 /*(mbedtls_ecdsa_write_signature() writes signature in ASN.1)*/
2854 /* parse ASN.1 to get r and s and lengths */
2855 u8 *p = buf, *r, *s;
2856 u8 *end = p + sig_len;
2857 size_t rlen, slen;
2858 mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
2859 mbedtls_asn1_get_tag(&p, end, &rlen, MBEDTLS_ASN1_INTEGER);
2860 r = p;
2861 p += rlen;
2862 mbedtls_asn1_get_tag(&p, end, &slen, MBEDTLS_ASN1_INTEGER);
2863 s = p;
2864
2865 /* write raw r and s into out
2866 * (including removal of leading 0 if added for ASN.1 integer)
2867 * note: DPP caller expects raw r, s each padded to prime len */
2868 mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
2869 size_t plen = CRYPTO_EC_plen(ecp_kp_grp);
2870 if (rlen > plen)
2871 {
2872 r += (rlen - plen);
2873 rlen = plen;
2874 }
2875 if (slen > plen)
2876 {
2877 s += (slen - plen);
2878 slen = plen;
2879 }
2880 struct wpabuf *out = wpabuf_alloc(plen * 2);
2881 if (out)
2882 {
2883 wpabuf_put(out, plen * 2);
2884 p = wpabuf_mhead_u8(out);
2885 os_memset(p, 0, plen * 2);
2886 os_memcpy(p + plen * 1 - rlen, r, rlen);
2887 os_memcpy(p + plen * 2 - slen, s, slen);
2888 }
2889 return out;
2890 }
2891 #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
2892
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)2893 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, size_t len, const u8 *sig, size_t sig_len)
2894 {
2895 switch (mbedtls_pk_verify((mbedtls_pk_context *)key, crypto_ec_key_sign_md(len), data, len, sig, sig_len))
2896 {
2897 case 0:
2898 /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*/ /* XXX: allow? */
2899 return 1;
2900 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
2901 return 0;
2902 default:
2903 return -1;
2904 }
2905 }
2906
2907 #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
crypto_ec_key_verify_signature_r_s(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * r,size_t r_len,const u8 * s,size_t s_len)2908 int crypto_ec_key_verify_signature_r_s(
2909 struct crypto_ec_key *key, const u8 *data, size_t len, const u8 *r, size_t r_len, const u8 *s, size_t s_len)
2910 {
2911 /* reimplement mbedtls_ecdsa_read_signature() without encoding r and s
2912 * into ASN.1 just for mbedtls_ecdsa_read_signature() to decode ASN.1 */
2913 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
2914 if (ecp_kp == NULL)
2915 return -1;
2916 mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp);
2917 mbedtls_ecp_point *ecp_kp_Q = &ecp_kp->MBEDTLS_PRIVATE(Q);
2918
2919 mbedtls_mpi mpi_r;
2920 mbedtls_mpi mpi_s;
2921 mbedtls_mpi_init(&mpi_r);
2922 mbedtls_mpi_init(&mpi_s);
2923 int ret = mbedtls_mpi_read_binary(&mpi_r, r, r_len) || mbedtls_mpi_read_binary(&mpi_s, s, s_len) ? -1 : 0;
2924 if (ret == 0)
2925 {
2926 ret = mbedtls_ecdsa_verify(ecp_kp_grp, data, len, ecp_kp_Q, &mpi_r, &mpi_s);
2927 ret = ret ? ret == MBEDTLS_ERR_ECP_BAD_INPUT_DATA ? 0 : -1 : 1;
2928 }
2929 mbedtls_mpi_free(&mpi_r);
2930 mbedtls_mpi_free(&mpi_s);
2931 return ret;
2932 }
2933 #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
2934
crypto_ec_key_group(struct crypto_ec_key * key)2935 int crypto_ec_key_group(struct crypto_ec_key *key)
2936 {
2937 mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)key);
2938 if (ecp_kp == NULL)
2939 return -1;
2940 mbedtls_ecp_group *ecp_group = &ecp_kp->MBEDTLS_PRIVATE(grp);
2941 return crypto_mbedtls_ike_id_from_ecp_group_id(ecp_group->id);
2942 }
2943
2944 #ifdef CRYPTO_MBEDTLS_CRYPTO_EC_DPP
2945
crypto_ec_key_cmp(struct crypto_ec_key * key1,struct crypto_ec_key * key2)2946 int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
2947 {
2948 mbedtls_ecp_keypair *ecp_kp1 = mbedtls_pk_ec(*(mbedtls_pk_context *)key1);
2949 mbedtls_ecp_keypair *ecp_kp2 = mbedtls_pk_ec(*(mbedtls_pk_context *)key2);
2950 if (ecp_kp1 == NULL || ecp_kp2 == NULL)
2951 return -1;
2952 mbedtls_ecp_group *ecp_kp1_grp = &ecp_kp1->MBEDTLS_PRIVATE(grp);
2953 mbedtls_ecp_group *ecp_kp2_grp = &ecp_kp2->MBEDTLS_PRIVATE(grp);
2954 mbedtls_ecp_point *ecp_kp1_Q = &ecp_kp1->MBEDTLS_PRIVATE(Q);
2955 mbedtls_ecp_point *ecp_kp2_Q = &ecp_kp2->MBEDTLS_PRIVATE(Q);
2956 return ecp_kp1_grp->id != ecp_kp2_grp->id || mbedtls_ecp_point_cmp(ecp_kp1_Q, ecp_kp2_Q) ? -1 : 0;
2957 }
2958
crypto_ec_key_debug_print(const struct crypto_ec_key * key,const char * title)2959 void crypto_ec_key_debug_print(const struct crypto_ec_key *key, const char *title)
2960 {
2961 /* TBD: what info is desirable here and in what human readable format?*/
2962 /*(crypto_openssl.c prints a human-readably public key and attributes)*/
2963 wpa_printf(MSG_DEBUG, "%s: %s not implemented", title, __func__);
2964 }
2965
2966 #endif /* CRYPTO_MBEDTLS_CRYPTO_EC_DPP */
2967
2968 #endif /* CRYPTO_MBEDTLS_CRYPTO_EC */
2969
2970 #ifdef CRYPTO_MBEDTLS_CRYPTO_CSR
2971
2972 #include <mbedtls/x509_csr.h>
2973 #include <mbedtls/oid.h>
2974
crypto_csr_init(void)2975 struct crypto_csr *crypto_csr_init(void)
2976 {
2977 mbedtls_x509write_csr *csr = os_malloc(sizeof(*csr));
2978 if (csr != NULL)
2979 mbedtls_x509write_csr_init(csr);
2980 return (struct crypto_csr *)csr;
2981 }
2982
crypto_csr_verify(const struct wpabuf * req)2983 struct crypto_csr *crypto_csr_verify(const struct wpabuf *req)
2984 {
2985 /* future: look for alternatives to MBEDTLS_PRIVATE() access */
2986
2987 /* sole caller src/common/dpp_crypto.c:dpp_validate_csr()
2988 * uses (mbedtls_x509_csr *) to obtain CSR_ATTR_CHALLENGE_PASSWORD
2989 * so allocate different object (mbedtls_x509_csr *) and special-case
2990 * object when used in crypto_csr_get_attribute() and when free()d in
2991 * crypto_csr_deinit(). */
2992
2993 mbedtls_x509_csr *csr = os_malloc(sizeof(*csr));
2994 if (csr == NULL)
2995 return NULL;
2996 mbedtls_x509_csr_init(csr);
2997 const mbedtls_md_info_t *md_info;
2998 unsigned char digest[MBEDTLS_MD_MAX_SIZE];
2999 if (mbedtls_x509_csr_parse_der(csr, wpabuf_head(req), wpabuf_len(req)) == 0 &&
3000 (md_info = mbedtls_md_info_from_type(csr->MBEDTLS_PRIVATE(sig_md))) != NULL &&
3001 mbedtls_md(md_info, csr->cri.p, csr->cri.len, digest) == 0)
3002 {
3003 switch (mbedtls_pk_verify(&csr->pk, csr->MBEDTLS_PRIVATE(sig_md), digest, mbedtls_md_get_size(md_info),
3004 csr->MBEDTLS_PRIVATE(sig).p, csr->MBEDTLS_PRIVATE(sig).len))
3005 {
3006 case 0:
3007 /*case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:*/ /* XXX: allow? */
3008 return (struct crypto_csr *)((uintptr_t)csr | 1uL);
3009 default:
3010 break;
3011 }
3012 }
3013
3014 mbedtls_x509_csr_free(csr);
3015 os_free(csr);
3016 return NULL;
3017 }
3018
crypto_csr_deinit(struct crypto_csr * csr)3019 void crypto_csr_deinit(struct crypto_csr *csr)
3020 {
3021 if ((uintptr_t)csr & 1uL)
3022 {
3023 csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL);
3024 mbedtls_x509_csr_free((mbedtls_x509_csr *)csr);
3025 }
3026 else
3027 mbedtls_x509write_csr_free((mbedtls_x509write_csr *)csr);
3028 os_free(csr);
3029 }
3030
crypto_csr_set_ec_public_key(struct crypto_csr * csr,struct crypto_ec_key * key)3031 int crypto_csr_set_ec_public_key(struct crypto_csr *csr, struct crypto_ec_key *key)
3032 {
3033 mbedtls_x509write_csr_set_key((mbedtls_x509write_csr *)csr, (mbedtls_pk_context *)key);
3034 return 0;
3035 }
3036
crypto_csr_set_name(struct crypto_csr * csr,enum crypto_csr_name type,const char * name)3037 int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type, const char *name)
3038 {
3039 /* specialized for src/common/dpp_crypto.c */
3040
3041 /* sole caller src/common/dpp_crypto.c:dpp_build_csr()
3042 * calls this function only once, using type == CSR_NAME_CN
3043 * (If called more than once, this code would need to append
3044 * components to the subject name, which we could do by
3045 * appending to (mbedtls_x509write_csr *) private member
3046 * mbedtls_asn1_named_data *MBEDTLS_PRIVATE(subject)) */
3047
3048 const char *label;
3049 switch (type)
3050 {
3051 case CSR_NAME_CN:
3052 label = "CN=";
3053 break;
3054 case CSR_NAME_SN:
3055 label = "SN=";
3056 break;
3057 case CSR_NAME_C:
3058 label = "C=";
3059 break;
3060 case CSR_NAME_O:
3061 label = "O=";
3062 break;
3063 case CSR_NAME_OU:
3064 label = "OU=";
3065 break;
3066 default:
3067 return -1;
3068 }
3069
3070 size_t len = strlen(name);
3071 struct wpabuf *buf = wpabuf_alloc(3 + len + 1);
3072 if (buf == NULL)
3073 return -1;
3074 wpabuf_put_data(buf, label, strlen(label));
3075 wpabuf_put_data(buf, name, len + 1); /*(include trailing '\0')*/
3076 /* Note: 'name' provided is set as given and should be backslash-escaped
3077 * by caller when necessary, e.g. literal ',' which are not separating
3078 * components should be backslash-escaped */
3079
3080 int ret = mbedtls_x509write_csr_set_subject_name((mbedtls_x509write_csr *)csr, wpabuf_head(buf)) ? -1 : 0;
3081 wpabuf_free(buf);
3082 return ret;
3083 }
3084
3085 /* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */
3086 static const char OBJ_pkcs9_challengePassword[] = MBEDTLS_OID_PKCS9 "\x07";
3087
crypto_csr_set_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,int attr_type,const u8 * value,size_t len)3088 int crypto_csr_set_attribute(
3089 struct crypto_csr *csr, enum crypto_csr_attr attr, int attr_type, const u8 *value, size_t len)
3090 {
3091 /* specialized for src/common/dpp_crypto.c */
3092 /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes
3093 * attr == CSR_ATTR_CHALLENGE_PASSWORD
3094 * attr_type == ASN1_TAG_UTF8STRING */
3095
3096 const char *oid;
3097 size_t oid_len;
3098 switch (attr)
3099 {
3100 case CSR_ATTR_CHALLENGE_PASSWORD:
3101 oid = OBJ_pkcs9_challengePassword;
3102 oid_len = sizeof(OBJ_pkcs9_challengePassword) - 1;
3103 break;
3104 default:
3105 return -1;
3106 }
3107
3108 (void)oid;
3109 (void)oid_len;
3110
3111 /* mbedtls does not currently provide way to set an attribute in a CSR:
3112 * https://github.com/Mbed-TLS/mbedtls/issues/4886 */
3113 wpa_printf(MSG_ERROR,
3114 "mbedtls does not currently support setting challengePassword "
3115 "attribute in CSR");
3116 return -1;
3117 }
3118
mbedtls_x509_csr_attr_oid_value(mbedtls_x509_csr * csr,const char * oid,size_t oid_len,size_t * vlen,int * vtype)3119 const u8 *mbedtls_x509_csr_attr_oid_value(
3120 mbedtls_x509_csr *csr, const char *oid, size_t oid_len, size_t *vlen, int *vtype)
3121 {
3122 /* Note: mbedtls_x509_csr_parse_der() has parsed and validated CSR,
3123 * so validation checks are not repeated here
3124 *
3125 * It would be nicer if (mbedtls_x509_csr *) had an mbedtls_x509_buf of
3126 * Attributes (or at least a pointer) since mbedtls_x509_csr_parse_der()
3127 * already parsed the rest of CertificationRequestInfo, some of which is
3128 * repeated here to step to Attributes. Since csr->subject_raw.p points
3129 * into csr->cri.p, which points into csr->raw.p, step over version and
3130 * subject of CertificationRequestInfo (SEQUENCE) */
3131 unsigned char *p = csr->subject_raw.p + csr->subject_raw.len;
3132 unsigned char *end = csr->cri.p + csr->cri.len, *ext;
3133 size_t len;
3134
3135 /* step over SubjectPublicKeyInfo */
3136 mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
3137 p += len;
3138
3139 /* Attributes
3140 * { ATTRIBUTE:IOSet } ::= SET OF { SEQUENCE { OID, value } }
3141 */
3142 if (mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0)
3143 {
3144 return NULL;
3145 }
3146 while (p < end)
3147 {
3148 if (mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0)
3149 {
3150 return NULL;
3151 }
3152 ext = p;
3153 p += len;
3154
3155 if (mbedtls_asn1_get_tag(&ext, end, &len, MBEDTLS_ASN1_OID) != 0)
3156 return NULL;
3157 if (oid_len != len || 0 != memcmp(ext, oid, oid_len))
3158 continue;
3159
3160 /* found oid; return value */
3161 *vtype = *ext++; /* tag */
3162 return (mbedtls_asn1_get_len(&ext, end, vlen) == 0) ? ext : NULL;
3163 }
3164
3165 return NULL;
3166 }
3167
crypto_csr_get_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,size_t * len,int * type)3168 const u8 *crypto_csr_get_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr, size_t *len, int *type)
3169 {
3170 /* specialized for src/common/dpp_crypto.c */
3171 /* sole caller src/common/dpp_crypto.c:dpp_build_csr() passes
3172 * attr == CSR_ATTR_CHALLENGE_PASSWORD */
3173
3174 const char *oid;
3175 size_t oid_len;
3176 switch (attr)
3177 {
3178 case CSR_ATTR_CHALLENGE_PASSWORD:
3179 oid = OBJ_pkcs9_challengePassword;
3180 oid_len = sizeof(OBJ_pkcs9_challengePassword) - 1;
3181 break;
3182 default:
3183 return NULL;
3184 }
3185
3186 /* see crypto_csr_verify(); expecting (mbedtls_x509_csr *) tagged |=1 */
3187 if (!((uintptr_t)csr & 1uL))
3188 return NULL;
3189 csr = (struct crypto_csr *)((uintptr_t)csr & ~1uL);
3190
3191 return mbedtls_x509_csr_attr_oid_value((mbedtls_x509_csr *)csr, oid, oid_len, len, type);
3192 }
3193
crypto_csr_sign(struct crypto_csr * csr,struct crypto_ec_key * key,enum crypto_hash_alg algo)3194 struct wpabuf *crypto_csr_sign(struct crypto_csr *csr, struct crypto_ec_key *key, enum crypto_hash_alg algo)
3195 {
3196 mbedtls_md_type_t sig_md;
3197 switch (algo)
3198 {
3199 case CRYPTO_HASH_ALG_SHA256:
3200 sig_md = MBEDTLS_MD_SHA256;
3201 break;
3202 case CRYPTO_HASH_ALG_SHA384:
3203 sig_md = MBEDTLS_MD_SHA384;
3204 break;
3205 case CRYPTO_HASH_ALG_SHA512:
3206 sig_md = MBEDTLS_MD_SHA512;
3207 break;
3208 default:
3209 return NULL;
3210 }
3211 mbedtls_x509write_csr_set_md_alg((mbedtls_x509write_csr *)csr, sig_md);
3212
3213 unsigned char buf[4096]; /* XXX: large enough? too large? */
3214 int len = mbedtls_x509write_csr_der((mbedtls_x509write_csr *)csr, buf, sizeof(buf), hostap_rng_fn, hostap_rng_ctx());
3215 if (len < 0)
3216 return NULL;
3217 /* Note: data is written at the end of the buffer! Use the
3218 * return value to determine where you should start
3219 * using the buffer */
3220 return wpabuf_alloc_copy(buf + sizeof(buf) - len, (size_t)len);
3221 }
3222
3223 #endif /* CRYPTO_MBEDTLS_CRYPTO_CSR */
3224
3225 #ifdef CRYPTO_MBEDTLS_CRYPTO_PKCS7
crypto_pkcs7_get_certificates(const struct wpabuf * pkcs7)3226 struct wpabuf *crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
3227 {
3228 return NULL;
3229 }
3230 #endif /* CRYPTO_MBEDTLS_CRYPTO_PKCS7 */
3231
3232 #endif
3233