• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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