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