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