1 /*
2 * Wrapper functions for mbedtls libcrypto
3 * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "crypto_mbedtls.h"
10 #include "securec.h"
11 #include "utils/common.h"
12 #include "crypto/crypto.h"
13 #include "mbedtls/ecp.h"
14 #include "mbedtls/bignum.h"
15 #include "mbedtls/dhm.h"
16 #include "mbedtls/md.h"
17 #include "mbedtls/cmac.h"
18 #include "mbedtls/aes.h"
19 #include "mbedtls/pkcs5.h"
20 #include "mbedtls/version.h"
21 #if defined(CONFIG_ECC) && defined(MBEDTLS_ECP_RESTARTABLE)
22 #include "mbedtls/ecdh.h"
23 #include "mbedtls/pk.h"
24 #endif
25
26 #ifdef SUPPORT_WATCHDOG
27 #include "watchdog.h"
28 #endif
29
30 #if defined(MBEDTLS_NIST_KW_C)
31 #include "mbedtls/nist_kw.h"
32 #endif
33 #include "utils/const_time.h"
34 #if defined(__LITEOS__)
35 #include "trng.h"
36 #endif
37
38 __attribute__((weak)) int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
39
get_trng(void * p_rng,unsigned char * buf,size_t len)40 static int get_trng(void *p_rng, unsigned char *buf, size_t len)
41 {
42 (void)p_rng;
43 #if defined(__LITEOS__)
44 return uapi_drv_cipher_trng_get_random_bytes(buf, len) ? -1 : 0;
45 #else
46 return 0;
47 #endif
48 }
49
crypto_get_random(void * buf,size_t len)50 int crypto_get_random(void *buf, size_t len)
51 {
52 #if defined(__LITEOS__) && !defined(WS53_PRODUCT_FPGA)
53 return uapi_drv_cipher_trng_get_random_bytes(buf, len) ? -1 : 0;
54 #else
55 return 0;
56 #endif
57 }
58
mbedtls_digest_vector(const mbedtls_md_info_t * md_info,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)59 static int mbedtls_digest_vector(const mbedtls_md_info_t *md_info, size_t num_elem,
60 const u8 *addr[], const size_t *len, u8 *mac)
61 {
62 mbedtls_md_context_t ctx;
63 size_t i;
64 int ret;
65
66 if (md_info == NULL || addr == NULL || len == NULL || mac == NULL)
67 return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
68
69 mbedtls_md_init(&ctx);
70
71 if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0)
72 goto cleanup;
73
74 if ((ret = mbedtls_md_starts(&ctx)) != 0)
75 goto cleanup;
76
77 for (i = 0; i < num_elem; i++) {
78 if ((ret = mbedtls_md_update(&ctx, addr[i], len[i])) != 0)
79 goto cleanup;
80 }
81
82 if ((ret = mbedtls_md_finish(&ctx, mac)) != 0)
83 goto cleanup;
84
85 cleanup:
86 mbedtls_md_free(&ctx);
87
88 return ret;
89 }
90
91 #ifndef CONFIG_FIPS
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)92 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
93 {
94 #if (MBEDTLS_VERSION_NUMBER < 0x03000000)
95 return mbedtls_digest_vector(mbedtls_md_info_from_type(MBEDTLS_MD_MD4), num_elem, addr, len, mac);
96 #else
97 return mbedtls_digest_vector(NULL, num_elem, addr, len, mac);
98 #endif
99 }
100 #endif /* CONFIG_FIPS */
101
102 #ifndef CONFIG_FIPS
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)103 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
104 {
105 return mbedtls_digest_vector(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), num_elem, addr, len, mac);
106 }
107 #endif /* CONFIG_FIPS */
108
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)109 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
110 {
111 return mbedtls_digest_vector(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), num_elem, addr, len, mac);
112 }
113
114 #ifndef NO_SHA256_WRAPPER
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)115 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
116 {
117 return mbedtls_digest_vector(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), num_elem, addr, len, mac);
118 }
119 #endif
120
121 #ifndef NO_SHA384_WRAPPER
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)122 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
123 {
124 return mbedtls_digest_vector(mbedtls_md_info_from_type(MBEDTLS_MD_SHA384), num_elem, addr, len, mac);
125 }
126 #endif
127
128 #ifndef NO_SHA512_WRAPPER
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)129 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
130 {
131 return mbedtls_digest_vector(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), num_elem, addr, len, mac);
132 }
133 #endif
134
mbedtls_hmac_vector(const mbedtls_md_info_t * md_info,const u8 * key,size_t keylen,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)135 int mbedtls_hmac_vector(const mbedtls_md_info_t *md_info,
136 const u8 *key, size_t keylen, size_t num_elem,
137 const u8 *addr[], const size_t *len, u8 *mac)
138 {
139 mbedtls_md_context_t ctx;
140 size_t i;
141 int ret;
142
143 if (md_info == NULL || key == NULL || addr == NULL || len == NULL || mac == NULL)
144 return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
145
146 mbedtls_md_init(&ctx);
147
148 if ((ret = mbedtls_md_setup(&ctx, md_info, 1)) != 0)
149 goto cleanup;
150
151 if ((ret = mbedtls_md_hmac_starts(&ctx, key, keylen)) != 0)
152 goto cleanup;
153
154 for (i = 0; i < num_elem; i++) {
155 if ((ret = mbedtls_md_hmac_update(&ctx, addr[i], len[i])) != 0)
156 goto cleanup;
157 }
158
159 if ((ret = mbedtls_md_hmac_finish(&ctx, mac)) != 0)
160 goto cleanup;
161
162 cleanup:
163 mbedtls_md_free(&ctx);
164
165 return ret;
166 }
167
pbkdf2_sha1(const char * passphrase,const u8 * ssid,size_t ssid_len,int iterations,u8 * buf,size_t buflen)168 int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, int iterations, u8 *buf, size_t buflen)
169 {
170 mbedtls_md_context_t sha1_ctx;
171 const mbedtls_md_info_t *info_sha1 = NULL;
172 int ret;
173 if ((passphrase == NULL) || (ssid == NULL) || (buf == NULL) ||
174 (ssid_len == 0) || (buflen == 0))
175 return -1;
176 mbedtls_md_init(&sha1_ctx);
177 info_sha1 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
178 if (info_sha1 == NULL) {
179 ret = -1;
180 goto cleanup;
181 }
182 if ((ret = mbedtls_md_setup(&sha1_ctx, info_sha1, 1)) != 0) {
183 ret = -1;
184 goto cleanup;
185 }
186
187 if (mbedtls_pkcs5_pbkdf2_hmac(&sha1_ctx, (const unsigned char *)passphrase, os_strlen(passphrase),
188 ssid, ssid_len, iterations, buflen, buf) != 0) {
189 ret = -1;
190 goto cleanup;
191 }
192 cleanup:
193 mbedtls_md_free(&sha1_ctx);
194 return ret;
195 }
196
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)197 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
198 const u8 *addr[], const size_t *len, u8 *mac)
199 {
200 return mbedtls_hmac_vector(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), key ,key_len, num_elem, addr, len, mac);
201 }
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)202 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
203 {
204 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
205 }
206
207 #ifdef CONFIG_SHA256
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)208 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
209 const u8 *addr[], const size_t *len, u8 *mac)
210 {
211 return mbedtls_hmac_vector(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), key ,key_len, num_elem, addr, len, mac);
212 }
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)213 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
214 {
215 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
216 }
217 #endif /* CONFIG_SHA256 */
218
219 #ifdef CONFIG_SHA384
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)220 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
221 const u8 *addr[], const size_t *len, u8 *mac)
222 {
223 return mbedtls_hmac_vector(mbedtls_md_info_from_type(MBEDTLS_MD_SHA384), key ,key_len, num_elem, addr, len, mac);
224 }
225
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)226 int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
227 {
228 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
229 }
230 #endif /* CONFIG_SHA384 */
231
232 #ifdef CONFIG_SHA512
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)233 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
234 const u8 *addr[], const size_t *len, u8 *mac)
235 {
236 return mbedtls_hmac_vector(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), key ,key_len, num_elem, addr, len, mac);
237 }
238
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)239 int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, size_t data_len, u8 *mac)
240 {
241 return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
242 }
243 #endif /* CONFIG_SHA512 */
244
get_group5_prime(mbedtls_mpi * p)245 static void get_group5_prime(mbedtls_mpi *p)
246 {
247 static const unsigned char RFC3526_PRIME_1536[] = {
248 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
249 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
250 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
251 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
252 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
253 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
254 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
255 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
256 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
257 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
258 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
259 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
260 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
261 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
262 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
263 0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
264 };
265 mbedtls_mpi_init(p);
266 (void)mbedtls_mpi_read_binary(p, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536));
267 return;
268 }
269
aes_encrypt_init(const u8 * key,size_t len)270 void *aes_encrypt_init(const u8 *key, size_t len)
271 {
272 mbedtls_aes_context *ctx = NULL;
273
274 if (key == NULL)
275 return NULL;
276 ctx = os_zalloc(sizeof(mbedtls_aes_context));
277 if (ctx == NULL)
278 return NULL;
279 mbedtls_aes_init(ctx);
280 if (mbedtls_aes_setkey_enc(ctx, key, (len * 8)) != 0) {
281 os_free(ctx);
282 ctx = NULL;
283 }
284 return ctx;
285 }
286
aes_encrypt(void * ctx,const u8 * plain,u8 * crypt)287 int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
288 {
289 if (ctx == NULL || plain == NULL || crypt == NULL)
290 return -1;
291
292 return (mbedtls_internal_aes_encrypt(ctx, plain, crypt) < 0) ? -1 : 0;
293 }
294
aes_encrypt_deinit(void * ctx)295 void aes_encrypt_deinit(void *ctx)
296 {
297 if (ctx == NULL)
298 return;
299 mbedtls_aes_free(ctx);
300 os_free(ctx);
301 }
302
aes_decrypt_init(const u8 * key,size_t len)303 void *aes_decrypt_init(const u8 *key, size_t len)
304 {
305 mbedtls_aes_context *ctx = NULL;
306
307 if (key == NULL)
308 return NULL;
309
310 ctx = os_zalloc(sizeof(mbedtls_aes_context));
311 if (ctx == NULL)
312 return NULL;
313 mbedtls_aes_init(ctx);
314 if (mbedtls_aes_setkey_dec(ctx, key, (len * 8)) != 0) {
315 os_free(ctx);
316 ctx = NULL;
317 }
318
319 return ctx;
320 }
321
aes_decrypt(void * ctx,const u8 * crypt,u8 * plain)322 int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
323 {
324 if (ctx == NULL || plain == NULL || crypt == NULL)
325 return -1;
326
327 return (mbedtls_internal_aes_decrypt(ctx, crypt, plain) < 0) ? -1 : 0;
328 }
329
aes_decrypt_deinit(void * ctx)330 void aes_decrypt_deinit(void *ctx)
331 {
332 if (ctx == NULL)
333 return;
334 mbedtls_aes_free(ctx);
335 os_free(ctx);
336 }
337
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)338 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
339 {
340 mbedtls_aes_context ctx = { 0 };
341 u8 temp_iv[16] = { 0 }; /* 16: iv length */
342 int ret;
343
344 if (key == NULL || iv == NULL || data == NULL)
345 return -1;
346 (void)os_memcpy(temp_iv, iv, 16);
347 mbedtls_aes_init(&ctx);
348 if (mbedtls_aes_setkey_enc(&ctx, key, AES_128_CRYPTO_LEN) != 0)
349 return -1;
350
351 ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, data_len, temp_iv, data, data);
352 mbedtls_aes_free(&ctx);
353 return ret;
354 }
355
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)356 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
357 {
358 mbedtls_aes_context ctx = { 0 };
359 u8 temp_iv[16] = { 0 }; /* 16: iv length */
360 int ret;
361
362 if (key == NULL || iv == NULL || data == NULL)
363 return -1;
364 (void)os_memcpy(temp_iv, iv, 16);
365 mbedtls_aes_init(&ctx);
366 if (mbedtls_aes_setkey_dec(&ctx, key, AES_128_CRYPTO_LEN) != 0)
367 return -1;
368
369 ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, data_len, temp_iv, data, data);
370 mbedtls_aes_free(&ctx);
371 return ret;
372 }
373
dh5_init(struct wpabuf ** priv,struct wpabuf ** publ)374 void *dh5_init(struct wpabuf **priv, struct wpabuf **publ)
375 {
376 mbedtls_dhm_context *dh = NULL;
377 struct wpabuf *pubkey = NULL;
378 struct wpabuf *privkey = NULL;
379 size_t publen, privlen;
380 unsigned char *export = NULL;
381 size_t exportlen;
382 if ((priv == NULL) || (publ == NULL))
383 return NULL;
384 if (*priv != NULL) {
385 wpabuf_free(*priv);
386 *priv = NULL;
387 }
388 if (*publ != NULL) {
389 wpabuf_free(*publ);
390 *publ = NULL;
391 }
392 dh = os_zalloc(sizeof(*dh));
393 if (dh == NULL)
394 return NULL;
395
396 mbedtls_dhm_init(dh);
397 mbedtls_mpi_init(&dh->G);
398 if (mbedtls_mpi_lset(&dh->G, DHM_PARM_G_LEN) != 0) {
399 os_free(dh);
400 return NULL;
401 }
402 get_group5_prime(&dh->P);
403
404 export = os_zalloc(DHM_PARM_MEM);
405 if (export == NULL)
406 goto err;
407 if (mbedtls_dhm_make_params(dh, (int)mbedtls_mpi_size(&dh->P), export, &exportlen, get_trng, NULL) != 0)
408 goto err;
409
410 os_free(export);
411 export = NULL;
412 publen = mbedtls_mpi_size((const mbedtls_mpi *)&(dh->GX));
413 pubkey = wpabuf_alloc(publen);
414 if (pubkey == NULL)
415 goto err;
416
417 privlen = mbedtls_mpi_size((const mbedtls_mpi *)&dh->X);
418 privkey = wpabuf_alloc(privlen);
419 if (privkey == NULL)
420 goto err;
421
422 mbedtls_mpi_write_binary((const mbedtls_mpi *)&dh->GX, wpabuf_put(pubkey, publen), publen);
423 mbedtls_mpi_write_binary((const mbedtls_mpi *)&dh->X, wpabuf_put(privkey, privlen), privlen);
424 *priv = privkey;
425 *publ = pubkey;
426 return dh;
427 err:
428 wpabuf_clear_free(pubkey);
429 wpabuf_clear_free(privkey);
430 mbedtls_dhm_free(dh);
431 os_free(export);
432 os_free(dh);
433 return NULL;
434 }
435
dh5_init_fixed(const struct wpabuf * priv,const struct wpabuf * publ)436 void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
437 {
438 mbedtls_dhm_context *dh = NULL;
439 unsigned char *export = NULL;
440 size_t exportlen;
441 struct wpabuf *pubkey = NULL;
442 struct wpabuf *privkey = NULL;
443 size_t publen, privlen;
444 if ((priv == NULL) || (publ == NULL))
445 return NULL;
446
447 dh = os_zalloc(sizeof(*dh));
448 if (dh == NULL)
449 return NULL;
450
451 mbedtls_dhm_init(dh);
452 mbedtls_mpi_init(&dh->G);
453 if (mbedtls_mpi_lset(&dh->G, DHM_PARM_G_LEN) != 0) {
454 os_free(dh);
455 return NULL;
456 }
457 get_group5_prime(&dh->P);
458
459 if (mbedtls_mpi_read_binary(&dh->X, wpabuf_head(priv), wpabuf_len(priv)) != 0)
460 goto err;
461
462 if (mbedtls_mpi_read_binary(&dh->GX, wpabuf_head(publ), wpabuf_len(publ)) != 0)
463 goto err;
464
465 export = os_zalloc(DHM_PARM_MEM);
466 if (export == NULL)
467 goto err;
468 if (mbedtls_dhm_make_params(dh, (int)mbedtls_mpi_size(&dh->P), export, &exportlen, get_trng, NULL) != 0)
469 goto err;
470
471 os_free(export);
472 export = NULL;
473 publen = mbedtls_mpi_size((const mbedtls_mpi *)&(dh->GX));
474 pubkey = wpabuf_alloc(publen);
475 if (pubkey == NULL)
476 goto err;
477
478 privlen = mbedtls_mpi_size((const mbedtls_mpi *)&dh->X);
479 privkey = wpabuf_alloc(privlen);
480 if (privkey == NULL)
481 goto err;
482
483 mbedtls_mpi_write_binary((const mbedtls_mpi *)&dh->GX, wpabuf_put(pubkey, publen), publen);
484 mbedtls_mpi_write_binary((const mbedtls_mpi *)&dh->X, wpabuf_put(privkey, privlen), privlen);
485 wpabuf_clear_free(pubkey);
486 wpabuf_clear_free(privkey);
487 return dh;
488 err:
489 wpabuf_clear_free(pubkey);
490 wpabuf_clear_free(privkey);
491 mbedtls_dhm_free(dh);
492 os_free(export);
493 os_free(dh);
494 return NULL;
495 }
496
dh5_derive_shared(void * ctx,const struct wpabuf * peer_public,const struct wpabuf * own_private)497 struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, const struct wpabuf *own_private)
498 {
499 struct wpabuf *res = NULL;
500 size_t rlen;
501 mbedtls_dhm_context *dh = ctx;
502 size_t keylen;
503 (void)own_private;
504 if ((ctx == NULL) || (peer_public == NULL))
505 return NULL;
506 const u8 *p = wpabuf_head(peer_public);
507 if (p == NULL)
508 return NULL;
509
510 if (mbedtls_mpi_read_binary(&dh->GY, p, wpabuf_len(peer_public)) != 0)
511 goto err;
512
513 rlen = mbedtls_mpi_size((const mbedtls_mpi *)&(dh->P));
514 res = wpabuf_alloc(rlen);
515 if (res == NULL)
516 goto err;
517
518 if (mbedtls_dhm_calc_secret(dh, wpabuf_mhead(res), rlen, &keylen, get_trng, NULL) != 0)
519 goto err;
520
521 wpabuf_put(res, keylen);
522 mbedtls_mpi_free(&dh->GY);
523 return res;
524 err:
525 mbedtls_mpi_free(&dh->GY);
526 wpabuf_clear_free(res);
527 return NULL;
528 }
529
dh5_free(void * ctx)530 void dh5_free(void *ctx)
531 {
532 mbedtls_dhm_context *dh = NULL;
533 if (ctx == NULL)
534 return;
535 dh = ctx;
536 mbedtls_dhm_free(dh);
537 os_free(dh);
538 }
539
540
crypto_bignum_init(void)541 struct crypto_bignum *crypto_bignum_init(void)
542 {
543 mbedtls_mpi *p = NULL;
544 p = os_zalloc(sizeof(*p));
545 if (p == NULL)
546 return NULL;
547
548 mbedtls_mpi_init(p);
549 return p;
550 }
551
crypto_bignum_init_set(const u8 * buf,size_t len)552 struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len)
553 {
554 int ret;
555 mbedtls_mpi *p = NULL;
556
557 if (buf == NULL || len == 0)
558 return NULL;
559
560 p = crypto_bignum_init();
561 if (p == NULL)
562 return NULL;
563
564 ret = mbedtls_mpi_read_binary(p, buf, len);
565 if (ret != 0) {
566 crypto_bignum_deinit(p, 1);
567 p = NULL;
568 }
569 return p;
570 }
571
crypto_bignum_init_uint(unsigned int val)572 struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
573 {
574 unsigned int i;
575 unsigned int tmp = val;
576 u8 buf[sizeof(unsigned int)] = {0};
577 struct crypto_bignum *p = NULL;
578
579 p = crypto_bignum_init();
580 if (p == NULL)
581 return NULL;
582
583 for (i = 0; i < sizeof(unsigned int); i++) {
584 buf[i] = tmp & 0xFF;
585 tmp >>= 8; // 8 bits
586 }
587 if (mbedtls_mpi_read_binary_le(p, buf, sizeof(unsigned int)) != 0) {
588 crypto_bignum_deinit(p, 1);
589 p = NULL;
590 }
591
592 return p;
593 }
594
crypto_bignum_deinit(struct crypto_bignum * n,int clear)595 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
596 {
597 (void)clear;
598 if (n == NULL)
599 return;
600
601 mbedtls_mpi_free(n);
602 os_free(n);
603 }
604
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)605 int crypto_bignum_to_bin(const struct crypto_bignum *a, u8 *buf, size_t buflen, size_t padlen)
606 {
607 int ret;
608 size_t num_bytes;
609 size_t offset;
610
611 if (a == NULL || buf == NULL || padlen > buflen)
612 return -1;
613
614 num_bytes = mbedtls_mpi_size((const mbedtls_mpi *)a);
615 if (num_bytes > buflen)
616 return -1;
617
618 if (padlen > num_bytes)
619 offset = padlen - num_bytes;
620 else
621 offset = 0;
622
623 (void)os_memset(buf, 0, offset);
624 ret = mbedtls_mpi_write_binary((const mbedtls_mpi *)a, buf + offset, num_bytes);
625 if (ret)
626 return -1;
627
628 return num_bytes + offset;
629 }
630
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)631 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
632 {
633 int count = 0;
634 unsigned cmp = 0;
635 size_t n_size;
636 if ((m == NULL) || (r == NULL))
637 return -1;
638 n_size = mbedtls_mpi_size(m);
639 if (n_size == 0)
640 return -1;
641 do {
642 if (mbedtls_mpi_fill_random(r, n_size, get_trng, NULL))
643 return -1;
644
645 if (mbedtls_mpi_shift_r(r, 8 * n_size - mbedtls_mpi_bitlen(m)))
646 return -1;
647
648 if (++count > 30)
649 return -1;
650
651 if (mbedtls_mpi_lt_mpi_ct(r, m, &cmp))
652 return -1;
653 } while (mbedtls_mpi_cmp_int(r, 1 ) < 0 || cmp != 1);
654
655 return 0;
656 }
657
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)658 int crypto_bignum_add(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
659 {
660 if (a == NULL || b == NULL || c == NULL)
661 return -1;
662 return mbedtls_mpi_add_mpi((mbedtls_mpi *)c, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
663 }
664
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)665 int crypto_bignum_mod(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
666 {
667 if (a == NULL || b == NULL || c == NULL)
668 return -1;
669 return mbedtls_mpi_mod_mpi((mbedtls_mpi *)c, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
670 }
671
crypto_bignum_exptmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)672 int crypto_bignum_exptmod(const struct crypto_bignum *a, const struct crypto_bignum *b,
673 const struct crypto_bignum *c, struct crypto_bignum *d)
674 {
675 if (a == NULL || b == NULL || c == NULL || d == NULL)
676 return -1;
677 /* It takes 2.7 seconds for two basic boards to interact at one time.
678 If 10 basic boards interact at the same time, the watchdog cannot be feeded in time,
679 resulting in system abnormality. */
680 #ifdef SUPPORT_WATCHDOG
681 uapi_watchdog_kick();
682 #endif
683 return mbedtls_mpi_exp_mod((mbedtls_mpi *)d, (const mbedtls_mpi *)a,
684 (const mbedtls_mpi *)b, (const mbedtls_mpi *)c,
685 NULL);
686 }
687
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)688 int crypto_bignum_inverse(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
689 {
690 if (a == NULL || b == NULL || c == NULL)
691 return -1;
692 return mbedtls_mpi_inv_mod((mbedtls_mpi *)c, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
693 }
694
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)695 int crypto_bignum_sub(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
696 {
697 if (a == NULL || b == NULL || c == NULL)
698 return -1;
699 return mbedtls_mpi_sub_mpi((mbedtls_mpi *)c, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
700 }
701
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)702 int crypto_bignum_div(const struct crypto_bignum *a, const struct crypto_bignum *b, struct crypto_bignum *c)
703 {
704 if (a == NULL || b == NULL || c == NULL)
705 return -1;
706 return mbedtls_mpi_div_mpi((mbedtls_mpi *)c, NULL, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
707 }
708
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)709 int crypto_bignum_addmod(const struct crypto_bignum *a, const struct crypto_bignum *b,
710 const struct crypto_bignum *c, struct crypto_bignum *d)
711 {
712 int ret;
713 mbedtls_mpi mul;
714 if (a == NULL || b == NULL || c == NULL || d == NULL)
715 return -1;
716 mbedtls_mpi_init(&mul);
717 ret = mbedtls_mpi_add_mpi(&mul, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
718 if (ret == 0)
719 ret = mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, &mul, (const mbedtls_mpi *)c);
720
721 mbedtls_mpi_free(&mul);
722 return (ret == 0) ? 0 : -1;
723 }
724
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)725 int crypto_bignum_mulmod(const struct crypto_bignum *a, const struct crypto_bignum *b,
726 const struct crypto_bignum *c, struct crypto_bignum *d)
727 {
728 int ret;
729 mbedtls_mpi mul;
730 if (a == NULL || b == NULL || c == NULL || d == NULL)
731 return -1;
732 mbedtls_mpi_init(&mul);
733 ret = mbedtls_mpi_mul_mpi(&mul, (const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
734 if (ret == 0)
735 ret = mbedtls_mpi_mod_mpi((mbedtls_mpi *)d, &mul, (const mbedtls_mpi *)c);
736
737 mbedtls_mpi_free(&mul);
738 return (ret == 0) ? 0 : -1;
739 }
740
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)741 int crypto_bignum_sqrmod(const struct crypto_bignum *a,
742 const struct crypto_bignum *b,
743 struct crypto_bignum *c)
744 {
745 if ((a == NULL) || (b == NULL) || (c == NULL))
746 return -1;
747 return crypto_bignum_mulmod(a, a, b, c);
748 }
749
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)750 int crypto_bignum_rshift(const struct crypto_bignum *a, int n, struct crypto_bignum *r)
751 {
752 int ret;
753 if ((a == NULL) || (r == NULL) || (n <= 0))
754 return -1;
755 ret = mbedtls_mpi_copy((mbedtls_mpi *)r, (const mbedtls_mpi *)a);
756 if (ret == 0)
757 ret = mbedtls_mpi_shift_r((mbedtls_mpi *)r, n);
758
759 return ret;
760 }
761
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)762 int crypto_bignum_cmp(const struct crypto_bignum *a, const struct crypto_bignum *b)
763 {
764 if ((a == NULL) || (b == NULL)) {
765 if (a != NULL)
766 return -1;
767 else if (b != NULL)
768 return 1;
769 else
770 return 0;
771 }
772 return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *)a, (const mbedtls_mpi *)b);
773 }
774
crypto_bignum_bits(const struct crypto_bignum * a)775 int crypto_bignum_bits(const struct crypto_bignum *a)
776 {
777 if (a == NULL)
778 return -1;
779 return mbedtls_mpi_bitlen((const mbedtls_mpi *)a);
780 }
781
crypto_bignum_is_zero(const struct crypto_bignum * a)782 int crypto_bignum_is_zero(const struct crypto_bignum *a)
783 {
784 if (a == NULL)
785 return 0;
786 return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 0) == 0) ? 1 : 0;
787 }
788
crypto_bignum_is_one(const struct crypto_bignum * a)789 int crypto_bignum_is_one(const struct crypto_bignum *a)
790 {
791 if (a == NULL)
792 return 0;
793 return (mbedtls_mpi_cmp_int((const mbedtls_mpi *)a, 1) == 0) ? 1 : 0;
794 }
795
crypto_bignum_is_odd(const struct crypto_bignum * a)796 int crypto_bignum_is_odd(const struct crypto_bignum *a)
797 {
798 if (a == NULL)
799 return 0;
800 return ((a != NULL) && (a->p != NULL) && (a->n > 0) && (a->p[0] & 0x01)) ? 1 : 0;
801 }
802
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)803 int crypto_bignum_legendre(const struct crypto_bignum *a, const struct crypto_bignum *p)
804 {
805 int ret;
806 int res = -2;
807 unsigned int mask;
808 mbedtls_mpi t;
809 mbedtls_mpi exp;
810
811 if (a == NULL || p == NULL)
812 return res;
813
814 mbedtls_mpi_init(&t);
815 mbedtls_mpi_init(&exp);
816
817 /* exp = (p-1) / 2 */
818 ret = mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *)p, 1);
819 if (ret == 0)
820 ret = mbedtls_mpi_shift_r(&exp, 1);
821
822 if (ret == 0)
823 ret = crypto_bignum_exptmod(a, (const struct crypto_bignum *)&exp,
824 p, (struct crypto_bignum *)&t);
825
826 if (ret == 0) {
827 /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need to use
828 * constant time selection to avoid branches here. */
829 res = -1;
830 mask = const_time_eq(crypto_bignum_is_one((const struct crypto_bignum *)&t), 1);
831 res = const_time_select_int(mask, 1, res);
832 mask = const_time_eq(crypto_bignum_is_zero((const struct crypto_bignum *)&t), 1);
833 res = const_time_select_int(mask, 0, res);
834 }
835
836 mbedtls_mpi_free(&exp);
837 mbedtls_mpi_free(&t);
838 return res;
839 }
840
crypto_ec_init(int group)841 struct crypto_ec *crypto_ec_init(int group)
842 {
843 mbedtls_ecp_group_id id;
844
845 /* convert IANA ECC group ID to mbedtls ECC group ID */
846 switch (group) {
847 case 19:
848 id = MBEDTLS_ECP_DP_SECP256R1; /* for SAE */
849 break;
850 case 28:
851 id = MBEDTLS_ECP_DP_BP256R1; /* for MESH */
852 break;
853 default:
854 return NULL;
855 }
856
857 struct crypto_ec *ec = os_zalloc(sizeof(struct crypto_ec));
858 if (ec == NULL)
859 return NULL;
860
861 mbedtls_ecp_group *e = &ec->ecp;
862 mbedtls_ecp_group_init(e);
863 if (mbedtls_ecp_group_load(e, id)) {
864 crypto_ec_deinit(ec);
865 return NULL;
866 }
867
868 int ret;
869 mbedtls_mpi_init(&ec->a);
870 if (e->A.p == NULL)
871 ret = mbedtls_mpi_sub_int(&ec->a, &e->P, 3); /* 3: in mbedtls A = p - 3 */
872 else
873 ret = mbedtls_mpi_copy(&ec->a, &e->A);
874
875 if (ret != 0) {
876 crypto_ec_deinit(ec);
877 return NULL;
878 }
879 return ec;
880 }
881
crypto_ec_deinit(struct crypto_ec * ec)882 void crypto_ec_deinit(struct crypto_ec *ec)
883 {
884 if (ec != NULL) {
885 mbedtls_ecp_group_free(&ec->ecp);
886 mbedtls_mpi_free(&ec->a);
887 os_free(ec);
888 }
889 }
890
crypto_ec_point_init(struct crypto_ec * ec)891 struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *ec)
892 {
893 if (ec == NULL)
894 return NULL;
895
896 crypto_ec_point *p = os_zalloc(sizeof(*p));
897 if (p == NULL)
898 return NULL;
899
900 mbedtls_ecp_point_init(p);
901 if (mbedtls_mpi_lset(&p->Z, 1)) { // affine coordinate
902 crypto_ec_point_deinit(p, 1);
903 return NULL;
904 }
905
906 return p;
907 }
908
crypto_ec_point_deinit(struct crypto_ec_point * e,int clear)909 void crypto_ec_point_deinit(struct crypto_ec_point *e, int clear)
910 {
911 (void)clear;
912 if (e == NULL)
913 return;
914
915 mbedtls_ecp_point_free(e);
916 os_free(e);
917 }
918
crypto_ec_prime_len(struct crypto_ec * ec)919 size_t crypto_ec_prime_len(struct crypto_ec *ec)
920 {
921 if (ec == NULL)
922 return 0;
923 mbedtls_ecp_group *e = &ec->ecp;
924 return mbedtls_mpi_size(&e->P);
925 }
926
crypto_ec_prime_len_bits(struct crypto_ec * ec)927 size_t crypto_ec_prime_len_bits(struct crypto_ec *ec)
928 {
929 if (ec == NULL)
930 return 0;
931 mbedtls_ecp_group *e = &ec->ecp;
932 return mbedtls_mpi_bitlen(&e->P);
933 }
934
crypto_ec_order_len(struct crypto_ec * ec)935 size_t crypto_ec_order_len(struct crypto_ec *ec)
936 {
937 if (ec == NULL)
938 return 0;
939 mbedtls_ecp_group *e = &ec->ecp;
940 return mbedtls_mpi_size(&e->N);
941 }
942
crypto_ec_get_prime(struct crypto_ec * ec)943 const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *ec)
944 {
945 if (ec == NULL)
946 return NULL;
947 mbedtls_ecp_group *e = &ec->ecp;
948 return (const struct crypto_bignum *)&e->P;
949 }
950
crypto_ec_get_order(struct crypto_ec * ec)951 const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *ec)
952 {
953 if (ec == NULL)
954 return NULL;
955 mbedtls_ecp_group *e = &ec->ecp;
956 return (const struct crypto_bignum *)&e->N;
957 }
958
959 /* only for Weierstrass curves */
crypto_ec_get_a(struct crypto_ec * ec)960 const struct crypto_bignum *crypto_ec_get_a(struct crypto_ec *ec)
961 {
962 if (ec == NULL)
963 return NULL;
964
965 return (const struct crypto_bignum *)&ec->a; // a is member of ec.
966 }
967
968 /* only for Weierstrass curves */
crypto_ec_get_b(struct crypto_ec * ec)969 const struct crypto_bignum *crypto_ec_get_b(struct crypto_ec *ec)
970 {
971 if (ec == NULL)
972 return NULL;
973 mbedtls_ecp_group *e = &ec->ecp;
974 return (const struct crypto_bignum *) &e->B;
975 }
976
crypto_ec_point_to_bin(struct crypto_ec * ec,const struct crypto_ec_point * point,u8 * x,u8 * y)977 int crypto_ec_point_to_bin(struct crypto_ec *ec, const struct crypto_ec_point *point, u8 *x, u8 *y)
978 {
979 int ret = -1;
980 size_t len;
981 if ((ec == NULL) || (point == NULL))
982 return -1;
983 mbedtls_ecp_group *e = &ec->ecp;
984 len = mbedtls_mpi_size(&e->P);
985 if (x != NULL) {
986 ret = mbedtls_mpi_write_binary(&(((const mbedtls_ecp_point *)point)->X), x, len);
987 if (ret)
988 return ret;
989 }
990 if (y != NULL) {
991 ret = mbedtls_mpi_write_binary(&(((const mbedtls_ecp_point *)point)->Y), y, len);
992 if (ret)
993 return ret;
994 }
995
996 return ret;
997 }
998
crypto_ec_point_from_bin(struct crypto_ec * ec,const u8 * val)999 struct crypto_ec_point *crypto_ec_point_from_bin(struct crypto_ec *ec, const u8 *val)
1000 {
1001 int ret;
1002 size_t len;
1003 if (ec == NULL || val == NULL)
1004 return NULL;
1005
1006 crypto_ec_point *p = crypto_ec_point_init(ec);
1007 if (p == NULL)
1008 return NULL;
1009
1010 mbedtls_ecp_group *e = &ec->ecp;
1011 len = mbedtls_mpi_size(&e->P);
1012 ret = mbedtls_mpi_read_binary(&p->X, val, len);
1013 if (ret == 0)
1014 ret = mbedtls_mpi_read_binary(&p->Y, val + len, len);
1015
1016 if (ret) {
1017 mbedtls_ecp_point_free(p);
1018 os_free(p);
1019 return NULL;
1020 }
1021 return p;
1022 }
1023
crypto_ec_point_add(struct crypto_ec * ec,const struct crypto_ec_point * a,const struct crypto_ec_point * b,struct crypto_ec_point * c)1024 int crypto_ec_point_add(struct crypto_ec *ec, const struct crypto_ec_point *a,
1025 const struct crypto_ec_point *b, struct crypto_ec_point *c)
1026 {
1027 int ret;
1028 if (ec == NULL || a == NULL || b == NULL || c == NULL)
1029 return -1;
1030 mbedtls_ecp_group *e = &ec->ecp;
1031 #ifdef SUPPORT_WATCHDOG
1032 uapi_watchdog_kick();
1033 #endif
1034 crypto_bignum one;
1035 mbedtls_mpi_init(&one);
1036 ret = mbedtls_mpi_lset(&one, 1);
1037 if (ret == 0)
1038 ret = mbedtls_ecp_muladd(e, c, &one, a, &one, b);
1039
1040 mbedtls_mpi_free(&one);
1041 return ret;
1042 }
1043
1044 /*
1045 * Multiplication res = b * p
1046 */
crypto_ec_point_mul(struct crypto_ec * ec,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)1047 int crypto_ec_point_mul(struct crypto_ec *ec, const struct crypto_ec_point *p,
1048 const struct crypto_bignum *b,
1049 struct crypto_ec_point *res)
1050 {
1051 if (ec == NULL || p == NULL || b == NULL || res == NULL)
1052 return -1;
1053 mbedtls_ecp_group *e = &ec->ecp;
1054 #ifdef SUPPORT_WATCHDOG
1055 uapi_watchdog_kick();
1056 #endif
1057 return mbedtls_ecp_mul(e, res, b, p, get_trng, NULL) ? -1 : 0;
1058 }
1059
crypto_ec_point_invert(struct crypto_ec * ec,struct crypto_ec_point * p)1060 int crypto_ec_point_invert(struct crypto_ec *ec, struct crypto_ec_point *p)
1061 {
1062 if (ec == NULL || p == NULL)
1063 return -1;
1064 mbedtls_ecp_group *e = &ec->ecp;
1065 return mbedtls_mpi_sub_mpi(&p->Y, &e->P, &p->Y);
1066 }
1067
1068 // y_bit (first byte of compressed point) mod 2 odd : r = p - r
crypto_ec_point_solve_y_coord(struct crypto_ec * ec,struct crypto_ec_point * p,const struct crypto_bignum * x,int y_bit)1069 int crypto_ec_point_solve_y_coord(struct crypto_ec *ec,
1070 struct crypto_ec_point *p,
1071 const struct crypto_bignum *x, int y_bit)
1072 {
1073 int ret;
1074 mbedtls_mpi n;
1075 if (ec == NULL || p == NULL || x == NULL)
1076 return -1;
1077 // Calculate square root of r over finite field P:
1078 // r = sqrt(x^3 + ax + b) = (x^3 + ax + b) ^ ((P + 1) / 4) (mod P)
1079 struct crypto_bignum *y_sqr = crypto_ec_point_compute_y_sqr(ec, x);
1080 if (y_sqr == NULL)
1081 return -1;
1082
1083 mbedtls_ecp_group *e = &ec->ecp;
1084 mbedtls_mpi_init(&n);
1085
1086 ret = mbedtls_mpi_add_int(&n, &e->P, 1);
1087 if (ret == 0)
1088 ret = mbedtls_mpi_shift_r(&n, 2);
1089
1090 if (ret == 0)
1091 ret = mbedtls_mpi_exp_mod(y_sqr, y_sqr, &n, &e->P, NULL);
1092
1093 // If LSB(Y) != y_bit, then do Y = P - Y
1094 if ((y_bit != crypto_bignum_is_odd(y_sqr)) && (ret == 0))
1095 ret = mbedtls_mpi_sub_mpi(y_sqr, &e->P, y_sqr); // r = p - r
1096
1097 if (ret == 0) {
1098 if ((mbedtls_mpi_copy(&p->X, x) != 0) ||
1099 (mbedtls_mpi_copy(&p->Y, y_sqr) != 0))
1100 ret = -1;
1101 else
1102 ret = 0;
1103 }
1104
1105 mbedtls_mpi_free(&n);
1106 crypto_bignum_deinit(y_sqr, 1);
1107
1108 return ret;
1109 }
1110
crypto_ec_point_compute_y_sqr(struct crypto_ec * ec,const struct crypto_bignum * x)1111 struct crypto_bignum *crypto_ec_point_compute_y_sqr(struct crypto_ec *ec, const struct crypto_bignum *x)
1112 {
1113 int ret;
1114 if (ec == NULL || x == NULL)
1115 return NULL;
1116 mbedtls_ecp_group *e = &ec->ecp;
1117 struct crypto_bignum *y2 = crypto_bignum_init();
1118 if (y2 == NULL)
1119 return NULL;
1120
1121 ret = mbedtls_mpi_mul_mpi(y2, x, x);
1122 if (ret == 0)
1123 ret = mbedtls_mpi_mod_mpi(y2, y2, &e->P);
1124
1125 if (ret == 0) {
1126 if (e->A.p == NULL)
1127 ret = mbedtls_mpi_sub_int(y2, y2, 3); // Special case where a is -3
1128 else
1129 ret = mbedtls_mpi_add_mpi(y2, y2, &e->A);
1130
1131 if (ret == 0)
1132 ret = mbedtls_mpi_mod_mpi(y2, y2, &e->P);
1133 }
1134 if (ret == 0)
1135 ret = mbedtls_mpi_mul_mpi(y2, y2, x);
1136
1137 if (ret == 0)
1138 ret = mbedtls_mpi_mod_mpi(y2, y2, &e->P);
1139
1140 if (ret == 0)
1141 ret = mbedtls_mpi_add_mpi(y2, y2, &e->B);
1142
1143 if (ret == 0)
1144 ret = mbedtls_mpi_mod_mpi(y2, y2, &e->P);
1145
1146 if (ret) {
1147 crypto_bignum_deinit(y2, 1);
1148 return NULL;
1149 }
1150
1151 return y2;
1152 }
1153
crypto_ec_point_is_at_infinity(struct crypto_ec * ec,const struct crypto_ec_point * p)1154 int crypto_ec_point_is_at_infinity(struct crypto_ec *ec, const struct crypto_ec_point *p)
1155 {
1156 (void)ec;
1157 if (p == NULL)
1158 return 0;
1159 return mbedtls_ecp_is_zero((struct crypto_ec_point *)p);
1160 }
1161
crypto_ec_point_is_on_curve(struct crypto_ec * ec,const struct crypto_ec_point * p)1162 int crypto_ec_point_is_on_curve(struct crypto_ec *ec, const struct crypto_ec_point *p)
1163 {
1164 if (ec == NULL || p == NULL)
1165 return 0;
1166 mbedtls_ecp_group *e = &ec->ecp;
1167 return mbedtls_ecp_check_pubkey(e, p) ? 0 : 1;
1168 }
1169
crypto_ec_point_cmp(const struct crypto_ec * ec,const struct crypto_ec_point * a,const struct crypto_ec_point * b)1170 int crypto_ec_point_cmp(const struct crypto_ec *ec,
1171 const struct crypto_ec_point *a,
1172 const struct crypto_ec_point *b)
1173 {
1174 (void)ec;
1175 if (a == NULL || b == NULL)
1176 return -1;
1177 return mbedtls_ecp_point_cmp(a, b);
1178 }
1179
1180 #if defined(CONFIG_ECC) && defined(MBEDTLS_ECP_RESTARTABLE)
1181
crypto_alloc_key(void)1182 static mbedtls_pk_context *crypto_alloc_key(void)
1183 {
1184 mbedtls_pk_context *key = os_malloc(sizeof(*key));
1185
1186 if (!key) {
1187 wpa_printf(MSG_ERROR, "%s: memory allocation failed\n", __func__);
1188 return NULL;
1189 }
1190 mbedtls_pk_init(key);
1191
1192 return key;
1193 }
1194
crypto_ec_free_key(mbedtls_pk_context * key)1195 void crypto_ec_free_key(mbedtls_pk_context *key)
1196 {
1197 mbedtls_pk_free(key);
1198 os_free(key);
1199 }
1200
crypto_ec_set_pubkey_point(const mbedtls_ecp_group * group,const u8 * buf,size_t len)1201 struct mbedtls_pk_context * crypto_ec_set_pubkey_point(const mbedtls_ecp_group *group,
1202 const u8 *buf, size_t len)
1203 {
1204 mbedtls_ecp_point *point = NULL;
1205 int ret;
1206 mbedtls_pk_context *key = (mbedtls_pk_context *)crypto_alloc_key();
1207
1208 if (!key) {
1209 wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__);
1210 return NULL;
1211 }
1212
1213 point = (mbedtls_ecp_point *)crypto_ec_point_from_bin((struct crypto_ec *)group, buf);
1214 if (!point) {
1215 wpa_printf(MSG_ERROR, "%s: Point initialization failed", __func__);
1216 goto fail;
1217 }
1218 if (crypto_ec_point_is_at_infinity((struct crypto_ec *)group, (struct crypto_ec_point *)point)) {
1219 wpa_printf(MSG_ERROR, "Point is at infinity");
1220 goto fail;
1221 }
1222 if (!crypto_ec_point_is_on_curve((struct crypto_ec *)group, (struct crypto_ec_point *)point)) {
1223 wpa_printf(MSG_ERROR, "Point not on curve");
1224 goto fail;
1225 }
1226
1227 if (mbedtls_ecp_check_pubkey((mbedtls_ecp_group *)group, point) < 0) { //typecast
1228 // ideally should have failed in upper condition, duplicate code??
1229 wpa_printf(MSG_ERROR, "Invalid key");
1230 goto fail;
1231 }
1232 /* Assign values */
1233 if( ( ret = mbedtls_pk_setup( key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY) ) ) != 0 )
1234 goto fail;
1235 mbedtls_ecp_copy(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(Q), point);
1236 mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
1237
1238 crypto_ec_point_deinit((struct crypto_ec_point *)point, 0);
1239 return key;
1240 fail:
1241 if (point)
1242 crypto_ec_point_deinit((struct crypto_ec_point *)point, 0);
1243 if (key)
1244 crypto_ec_free_key(key);
1245 return NULL;
1246 }
1247
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)1248 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
1249 {
1250 mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh;
1251 if (!ctx) {
1252 return;
1253 }
1254 mbedtls_ecdh_free(ctx);
1255 os_free(ctx);
1256 ctx = NULL;
1257 }
1258
crypto_mbedtls_get_grp_id(int group)1259 int crypto_mbedtls_get_grp_id(int group)
1260 {
1261 switch(group) {
1262 case 19:
1263 return MBEDTLS_ECP_DP_SECP256R1;
1264 case 20:
1265 return MBEDTLS_ECP_DP_SECP384R1;
1266 case 21:
1267 return MBEDTLS_ECP_DP_SECP521R1;
1268 default:
1269 return MBEDTLS_ECP_DP_NONE;
1270 }
1271 }
1272
crypto_ecdh_init(int group)1273 struct crypto_ecdh * crypto_ecdh_init(int group)
1274 {
1275 mbedtls_ecdh_context *ctx;
1276
1277 ctx = os_zalloc(sizeof(*ctx));
1278 if (!ctx) {
1279 wpa_printf(MSG_ERROR, "Memory allocation failed for ecdh context");
1280 goto fail;
1281 }
1282 mbedtls_ecdh_init(ctx);
1283
1284 if ((mbedtls_ecp_group_load(&ctx->MBEDTLS_PRIVATE(grp), crypto_mbedtls_get_grp_id(group))) != 0) {
1285 wpa_printf(MSG_ERROR, "Failed to set up ECDH context with group info");
1286 goto fail;
1287 }
1288
1289 /* Generates ECDH keypair on elliptic curve */
1290 if (mbedtls_ecdh_gen_public(&ctx->MBEDTLS_PRIVATE(grp), &ctx->MBEDTLS_PRIVATE(d),
1291 &ctx->MBEDTLS_PRIVATE(Q), get_trng, NULL) !=0) {
1292 wpa_printf(MSG_ERROR, "ECDH keypair on curve failed");
1293 goto fail;
1294 }
1295
1296 return (struct crypto_ecdh *)ctx;
1297 fail:
1298 if (ctx) {
1299 mbedtls_ecdh_free(ctx);
1300 os_free(ctx);
1301 ctx = NULL;
1302 }
1303 return NULL;
1304 }
1305
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int y)1306 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int y)
1307 {
1308 struct wpabuf *public_key = NULL;
1309 uint8_t *buf = NULL;
1310 mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh;
1311 size_t prime_len = ctx->MBEDTLS_PRIVATE(grp).pbits/8;
1312
1313 buf = os_zalloc(y ? prime_len : 2 * prime_len);
1314 if (!buf) {
1315 wpa_printf(MSG_ERROR, "Memory allocation failed");
1316 return NULL;
1317 }
1318
1319 /* Export an MPI into unsigned big endian binary data of fixed size */
1320 mbedtls_mpi_write_binary(&ctx->MBEDTLS_PRIVATE(Q).X, buf, prime_len);
1321 public_key = wpabuf_alloc_copy(buf, 32);
1322 os_free(buf);
1323 return public_key;
1324 }
1325
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)1326 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, const u8 *key, size_t len)
1327 {
1328 uint8_t *secret = 0;
1329 size_t olen = 0, len_prime = 0;
1330 struct crypto_bignum *bn_x = NULL;
1331 struct crypto_ec_point *ec_pt = NULL;
1332 uint8_t *px = NULL, *py = NULL, *buf = NULL;
1333 mbedtls_pk_context *peer = NULL;
1334 struct wpabuf *sh_secret = NULL;
1335 int secret_key = 0;
1336
1337 mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh;
1338
1339 len_prime = ctx->MBEDTLS_PRIVATE(grp).pbits/8;
1340 bn_x = crypto_bignum_init_set(key, len);
1341
1342 /* Initialize data for EC point */
1343 ec_pt = crypto_ec_point_init((struct crypto_ec*)&ctx->MBEDTLS_PRIVATE(grp));
1344 if (!ec_pt) {
1345 wpa_printf(MSG_ERROR,"Initializing for EC point failed");
1346 goto cleanup;
1347 }
1348
1349 if (crypto_ec_point_solve_y_coord((struct crypto_ec*)&ctx->MBEDTLS_PRIVATE(grp), ec_pt, bn_x, inc_y) != 0) {
1350 wpa_printf(MSG_ERROR,"Failed to solve for y coordinate");
1351 goto cleanup;
1352 }
1353 px = os_zalloc(len);
1354 py = os_zalloc(len);
1355 buf = os_zalloc(2*len);
1356
1357 if (!px || !py || !buf) {
1358 wpa_printf(MSG_ERROR, "Memory allocation failed");
1359 goto cleanup;
1360 }
1361 if (crypto_ec_point_to_bin((struct crypto_ec*)&ctx->MBEDTLS_PRIVATE(grp), ec_pt, px, py) != 0) {
1362 wpa_printf(MSG_ERROR,"Failed to write EC point value as binary data");
1363 goto cleanup;
1364 }
1365
1366 os_memcpy(buf, px, len);
1367 os_memcpy(buf+len, py, len);
1368
1369 peer = crypto_ec_set_pubkey_point((mbedtls_ecp_group *)&ctx->MBEDTLS_PRIVATE(grp), buf, len);
1370 if (!peer) {
1371 wpa_printf(MSG_ERROR, "Failed to set point for peer's public key");
1372 goto cleanup;
1373 }
1374
1375 /* Setup ECDH context from EC key */
1376 /* Call to mbedtls_ecdh_get_params() will initialize the context when not LEGACY context */
1377 if (ctx != NULL && peer != NULL) {
1378 mbedtls_ecp_copy(&ctx->MBEDTLS_PRIVATE(Qp), &(mbedtls_pk_ec(*peer))->MBEDTLS_PRIVATE(Q));
1379 } else {
1380 wpa_printf(MSG_ERROR, "Failed to set peer's ECDH context");
1381 goto cleanup;
1382 }
1383 int len_secret = inc_y ? 2*len : len;
1384 secret = os_zalloc(len_secret);
1385 if (!secret) {
1386 wpa_printf(MSG_ERROR, "Allocation failed for secret");
1387 goto cleanup;
1388 }
1389
1390 /* Calculate secret
1391 z = F(DH(x,Y)) */
1392 secret_key = mbedtls_ecdh_calc_secret(ctx, &olen, secret, len_prime, get_trng, NULL);
1393 if (secret_key != 0) {
1394 wpa_printf(MSG_ERROR, "Calculation of secret failed");
1395 goto cleanup;
1396 }
1397 sh_secret = wpabuf_alloc_copy(secret, len_secret);
1398
1399 cleanup:
1400 os_free(px);
1401 os_free(py);
1402 os_free(buf);
1403 os_free(secret);
1404 crypto_ec_free_key(peer);
1405 crypto_bignum_deinit(bn_x, 1);
1406 crypto_ec_point_deinit(ec_pt, 1);
1407 return sh_secret;
1408 }
1409
1410 #endif /* defined(CONFIG_ECC) && defined(MBEDTLS_ECP_RESTARTABLE) */
1411
1412