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