1 /*
2  * Wrapper functions for libwolfssl
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 "includes.h"
10 
11 #include "common.h"
12 #include "crypto.h"
13 #include "tls/asn1.h"
14 
15 /* wolfSSL headers */
16 #include <wolfssl/options.h> /* options.h needs to be included first */
17 #include <wolfssl/version.h>
18 #include <wolfssl/openssl/bn.h>
19 #include <wolfssl/wolfcrypt/aes.h>
20 #include <wolfssl/wolfcrypt/arc4.h>
21 #include <wolfssl/wolfcrypt/asn.h>
22 #include <wolfssl/wolfcrypt/asn_public.h>
23 #include <wolfssl/wolfcrypt/cmac.h>
24 #include <wolfssl/wolfcrypt/des3.h>
25 #include <wolfssl/wolfcrypt/dh.h>
26 #include <wolfssl/wolfcrypt/ecc.h>
27 #include <wolfssl/wolfcrypt/error-crypt.h>
28 #include <wolfssl/wolfcrypt/hmac.h>
29 #include <wolfssl/wolfcrypt/md4.h>
30 #include <wolfssl/wolfcrypt/md5.h>
31 #include <wolfssl/wolfcrypt/pkcs7.h>
32 #include <wolfssl/wolfcrypt/pwdbased.h>
33 #include <wolfssl/wolfcrypt/rsa.h>
34 #include <wolfssl/wolfcrypt/sha.h>
35 #include <wolfssl/wolfcrypt/sha256.h>
36 #include <wolfssl/wolfcrypt/sha512.h>
37 
38 #ifdef CONFIG_FIPS
39 #ifndef HAVE_FIPS
40 #warning "You are compiling wpa_supplicant/hostapd in FIPS mode but wolfSSL is not configured for FIPS mode."
41 #endif /* HAVE_FIPS */
42 #endif /* CONFIG_FIPS */
43 
44 
45 #ifdef CONFIG_FIPS
46 #if !defined(HAVE_FIPS_VERSION) || HAVE_FIPS_VERSION <= 2
47 #define WOLFSSL_OLD_FIPS
48 #endif
49 #endif
50 
51 #if LIBWOLFSSL_VERSION_HEX < 0x05004000
wc_EccPublicKeyToDer_ex(ecc_key * key,byte * output,word32 inLen,int with_AlgCurve,int comp)52 static int wc_EccPublicKeyToDer_ex(ecc_key *key, byte *output,
53 				   word32 inLen, int with_AlgCurve,
54 				   int comp)
55 {
56 	return wc_EccPublicKeyToDer(key, output, inLen, with_AlgCurve);
57 }
58 #endif /* version < 5.4.0 */
59 
60 #define LOG_WOLF_ERROR_VA(msg, ...) \
61 	wpa_printf(MSG_ERROR, "wolfSSL: %s:%d " msg, \
62 		   __func__, __LINE__, __VA_ARGS__)
63 
64 #define LOG_WOLF_ERROR(msg) \
65 	LOG_WOLF_ERROR_VA("%s", (msg))
66 
67 #define LOG_WOLF_ERROR_FUNC(func, err) \
68 	LOG_WOLF_ERROR_VA(#func " failed with err: %d %s", \
69 			  (err), wc_GetErrorString(err))
70 
71 #define LOG_WOLF_ERROR_FUNC_NULL(func) \
72 	LOG_WOLF_ERROR(#func " failed with NULL return")
73 
74 #define LOG_INVALID_PARAMETERS() \
75 	LOG_WOLF_ERROR("invalid input parameters")
76 
77 
78 /* Helper functions to make type allocation uniform */
79 
wc_rng_init(void)80 static WC_RNG * wc_rng_init(void)
81 {
82 	WC_RNG *ret;
83 
84 #ifdef CONFIG_FIPS
85 	ret = os_zalloc(sizeof(WC_RNG));
86 	if (!ret) {
87 		LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
88 	} else {
89 		int err;
90 
91 		err = wc_InitRng(ret);
92 		if (err != 0) {
93 			LOG_WOLF_ERROR_FUNC(wc_InitRng, err);
94 			os_free(ret);
95 			ret = NULL;
96 		}
97 	}
98 #else /* CONFIG_FIPS */
99 	ret = wc_rng_new(NULL, 0, NULL);
100 	if (!ret)
101 		LOG_WOLF_ERROR_FUNC_NULL(wc_rng_new);
102 #endif /* CONFIG_FIPS */
103 
104 	return ret;
105 }
106 
107 
wc_rng_deinit(WC_RNG * rng)108 static void wc_rng_deinit(WC_RNG *rng)
109 {
110 #ifdef CONFIG_FIPS
111 	wc_FreeRng(rng);
112 	os_free(rng);
113 #else /* CONFIG_FIPS */
114 	wc_rng_free(rng);
115 #endif /* CONFIG_FIPS */
116 }
117 
118 
ecc_key_init(void)119 static ecc_key * ecc_key_init(void)
120 {
121 	ecc_key *ret;
122 #ifdef CONFIG_FIPS
123 	int err;
124 
125 	ret = os_zalloc(sizeof(ecc_key));
126 	if (!ret) {
127 		LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
128 	} else {
129 		err = wc_ecc_init_ex(ret, NULL, INVALID_DEVID);
130 		if (err != 0) {
131 			LOG_WOLF_ERROR("wc_ecc_init_ex failed");
132 			os_free(ret);
133 			ret = NULL;
134 		}
135 	}
136 #else /* CONFIG_FIPS */
137 	ret = wc_ecc_key_new(NULL);
138 	if (!ret)
139 		LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_key_new);
140 #endif /* CONFIG_FIPS */
141 
142 	return ret;
143 }
144 
145 
ecc_key_deinit(ecc_key * key)146 static void ecc_key_deinit(ecc_key *key)
147 {
148 #ifdef CONFIG_FIPS
149 	wc_ecc_free(key);
150 	os_free(key);
151 #else /* CONFIG_FIPS */
152 	wc_ecc_key_free(key);
153 #endif /* CONFIG_FIPS */
154 }
155 
156 /* end of helper functions */
157 
158 
159 #ifndef CONFIG_FIPS
160 
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)161 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
162 {
163 	Md4 md4;
164 	size_t i;
165 
166 	if (TEST_FAIL())
167 		return -1;
168 
169 	wc_InitMd4(&md4);
170 
171 	for (i = 0; i < num_elem; i++)
172 		wc_Md4Update(&md4, addr[i], len[i]);
173 
174 	wc_Md4Final(&md4, mac);
175 
176 	return 0;
177 }
178 
179 
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)180 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
181 {
182 	wc_Md5 md5;
183 	size_t i;
184 	int err;
185 	int ret = -1;
186 
187 	if (TEST_FAIL())
188 		return -1;
189 
190 	err = wc_InitMd5(&md5);
191 	if (err != 0) {
192 		LOG_WOLF_ERROR_FUNC(wc_InitMd5, err);
193 		return -1;
194 	}
195 
196 	for (i = 0; i < num_elem; i++) {
197 		err = wc_Md5Update(&md5, addr[i], len[i]);
198 		if (err != 0) {
199 			LOG_WOLF_ERROR_FUNC(wc_Md5Update, err);
200 			goto fail;
201 		}
202 	}
203 
204 	err = wc_Md5Final(&md5, mac);
205 	if (err != 0) {
206 		LOG_WOLF_ERROR_FUNC(wc_Md5Final, err);
207 		goto fail;
208 	}
209 
210 	ret = 0;
211 fail:
212 	wc_Md5Free(&md5);
213 	return ret;
214 }
215 
216 #endif /* CONFIG_FIPS */
217 
218 
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)219 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
220 {
221 	wc_Sha sha;
222 	size_t i;
223 	int err;
224 	int ret = -1;
225 
226 	if (TEST_FAIL())
227 		return -1;
228 
229 	err = wc_InitSha(&sha);
230 	if (err != 0) {
231 		LOG_WOLF_ERROR_FUNC(wc_InitSha, err);
232 		return -1;
233 	}
234 
235 	for (i = 0; i < num_elem; i++) {
236 		err = wc_ShaUpdate(&sha, addr[i], len[i]);
237 		if (err != 0) {
238 			LOG_WOLF_ERROR_FUNC(wc_ShaUpdate, err);
239 			goto fail;
240 		}
241 	}
242 
243 	err = wc_ShaFinal(&sha, mac);
244 	if (err != 0) {
245 		LOG_WOLF_ERROR_FUNC(wc_ShaFinal, err);
246 		goto fail;
247 	}
248 
249 	ret = 0;
250 fail:
251 	wc_ShaFree(&sha);
252 	return ret;
253 }
254 
255 
256 #ifndef NO_SHA256_WRAPPER
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)257 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
258 		  u8 *mac)
259 {
260 	wc_Sha256 sha256;
261 	size_t i;
262 	int err;
263 	int ret = -1;
264 
265 	if (TEST_FAIL())
266 		return -1;
267 
268 	err = wc_InitSha256(&sha256);
269 	if (err != 0) {
270 		LOG_WOLF_ERROR_FUNC(wc_InitSha256, err);
271 		return -1;
272 	}
273 
274 	for (i = 0; i < num_elem; i++) {
275 		err = wc_Sha256Update(&sha256, addr[i], len[i]);
276 		if (err != 0) {
277 			LOG_WOLF_ERROR_FUNC(wc_Sha256Update, err);
278 			goto fail;
279 		}
280 	}
281 
282 	err = wc_Sha256Final(&sha256, mac);
283 	if (err != 0) {
284 		LOG_WOLF_ERROR_FUNC(wc_Sha256Final, err);
285 		goto fail;
286 	}
287 
288 	ret = 0;
289 fail:
290 	wc_Sha256Free(&sha256);
291 	return ret;
292 }
293 #endif /* NO_SHA256_WRAPPER */
294 
295 
296 #ifdef CONFIG_SHA384
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)297 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
298 		  u8 *mac)
299 {
300 	wc_Sha384 sha384;
301 	size_t i;
302 	int err;
303 	int ret = -1;
304 
305 	if (TEST_FAIL())
306 		return -1;
307 
308 	err = wc_InitSha384(&sha384);
309 	if (err != 0) {
310 		LOG_WOLF_ERROR_FUNC(wc_InitSha384, err);
311 		return -1;
312 	}
313 
314 	for (i = 0; i < num_elem; i++) {
315 		err = wc_Sha384Update(&sha384, addr[i], len[i]);
316 		if (err != 0) {
317 			LOG_WOLF_ERROR_FUNC(wc_Sha384Update, err);
318 			goto fail;
319 		}
320 	}
321 
322 	err = wc_Sha384Final(&sha384, mac);
323 	if (err != 0) {
324 		LOG_WOLF_ERROR_FUNC(wc_Sha384Final, err);
325 		goto fail;
326 	}
327 
328 	ret = 0;
329 fail:
330 	wc_Sha384Free(&sha384);
331 	return ret;
332 }
333 #endif /* CONFIG_SHA384 */
334 
335 
336 #ifdef CONFIG_SHA512
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)337 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
338 		  u8 *mac)
339 {
340 	wc_Sha512 sha512;
341 	size_t i;
342 	int err;
343 	int ret = -1;
344 
345 	if (TEST_FAIL())
346 		return -1;
347 
348 	err = wc_InitSha512(&sha512);
349 	if (err != 0) {
350 		LOG_WOLF_ERROR_FUNC(wc_InitSha512, err);
351 		return -1;
352 	}
353 
354 	for (i = 0; i < num_elem; i++) {
355 		err = wc_Sha512Update(&sha512, addr[i], len[i]);
356 		if (err != 0) {
357 			LOG_WOLF_ERROR_FUNC(wc_Sha512Update, err);
358 			goto fail;
359 		}
360 	}
361 
362 	err = wc_Sha512Final(&sha512, mac);
363 	if (err != 0) {
364 		LOG_WOLF_ERROR_FUNC(wc_Sha512Final, err);
365 		goto fail;
366 	}
367 
368 	ret = 0;
369 fail:
370 	wc_Sha512Free(&sha512);
371 	return ret;
372 }
373 #endif /* CONFIG_SHA512 */
374 
375 
wolfssl_hmac_vector(int type,const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,unsigned int mdlen)376 static int wolfssl_hmac_vector(int type, const u8 *key,
377 			       size_t key_len, size_t num_elem,
378 			       const u8 *addr[], const size_t *len, u8 *mac,
379 			       unsigned int mdlen)
380 {
381 	Hmac hmac;
382 	size_t i;
383 	int err;
384 	int ret = -1;
385 
386 	(void) mdlen;
387 
388 	if (TEST_FAIL())
389 		return -1;
390 
391 	err = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
392 	if (err != 0) {
393 		LOG_WOLF_ERROR_FUNC(wc_HmacInit, err);
394 		return -1;
395 	}
396 
397 	err = wc_HmacSetKey(&hmac, type, key, (word32) key_len);
398 	if (err != 0) {
399 		LOG_WOLF_ERROR_FUNC(wc_HmacSetKey, err);
400 		goto fail;
401 	}
402 
403 	for (i = 0; i < num_elem; i++) {
404 		err = wc_HmacUpdate(&hmac, addr[i], len[i]);
405 		if (err != 0) {
406 			LOG_WOLF_ERROR_FUNC(wc_HmacUpdate, err);
407 			goto fail;
408 		}
409 	}
410 	err = wc_HmacFinal(&hmac, mac);
411 	if (err != 0) {
412 		LOG_WOLF_ERROR_FUNC(wc_HmacFinal, err);
413 		goto fail;
414 	}
415 
416 	ret = 0;
417 fail:
418 	wc_HmacFree(&hmac);
419 	return ret;
420 }
421 
422 
423 #ifndef CONFIG_FIPS
424 
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)425 int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
426 		    const u8 *addr[], const size_t *len, u8 *mac)
427 {
428 	return wolfssl_hmac_vector(WC_MD5, key, key_len, num_elem, addr, len,
429 				   mac, 16);
430 }
431 
432 
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)433 int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
434 	     u8 *mac)
435 {
436 	return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
437 }
438 
439 #endif /* CONFIG_FIPS */
440 
441 
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)442 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
443 		     const u8 *addr[], const size_t *len, u8 *mac)
444 {
445 	return wolfssl_hmac_vector(WC_SHA, key, key_len, num_elem, addr, len,
446 				   mac, 20);
447 }
448 
449 
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)450 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
451 	      u8 *mac)
452 {
453 	return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
454 }
455 
456 
457 #ifdef CONFIG_SHA256
458 
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)459 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
460 		       const u8 *addr[], const size_t *len, u8 *mac)
461 {
462 	return wolfssl_hmac_vector(WC_SHA256, key, key_len, num_elem, addr, len,
463 				   mac, 32);
464 }
465 
466 
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)467 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
468 		size_t data_len, u8 *mac)
469 {
470 	return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
471 }
472 
473 #endif /* CONFIG_SHA256 */
474 
475 
476 #ifdef CONFIG_SHA384
477 
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)478 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
479 		       const u8 *addr[], const size_t *len, u8 *mac)
480 {
481 	return wolfssl_hmac_vector(WC_SHA384, key, key_len, num_elem, addr, len,
482 				   mac, 48);
483 }
484 
485 
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)486 int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
487 		size_t data_len, u8 *mac)
488 {
489 	return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
490 }
491 
492 #endif /* CONFIG_SHA384 */
493 
494 
495 #ifdef CONFIG_SHA512
496 
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)497 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
498 		       const u8 *addr[], const size_t *len, u8 *mac)
499 {
500 	return wolfssl_hmac_vector(WC_SHA512, key, key_len, num_elem, addr, len,
501 				   mac, 64);
502 }
503 
504 
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)505 int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
506 		size_t data_len, u8 *mac)
507 {
508 	return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
509 }
510 
511 #endif /* CONFIG_SHA512 */
512 
513 
pbkdf2_sha1(const char * passphrase,const u8 * ssid,size_t ssid_len,int iterations,u8 * buf,size_t buflen)514 int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
515 		int iterations, u8 *buf, size_t buflen)
516 {
517 	int ret;
518 
519 	PRIVATE_KEY_UNLOCK();
520 	ret = wc_PBKDF2(buf, (const byte *) passphrase, os_strlen(passphrase),
521 			ssid, ssid_len, iterations, buflen, WC_SHA);
522 	PRIVATE_KEY_LOCK();
523 	if (ret != 0) {
524 		if (ret == HMAC_MIN_KEYLEN_E) {
525 			LOG_WOLF_ERROR_VA("wolfSSL: Password is too short. Make sure your password is at least %d characters long. This is a requirement for FIPS builds.",
526 					  HMAC_FIPS_MIN_KEY);
527 		}
528 		return -1;
529 	}
530 	return 0;
531 }
532 
533 
534 #ifdef CONFIG_DES
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)535 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
536 {
537 	Des des;
538 	u8  pkey[8], next, tmp;
539 	int i;
540 
541 	/* Add parity bits to the key */
542 	next = 0;
543 	for (i = 0; i < 7; i++) {
544 		tmp = key[i];
545 		pkey[i] = (tmp >> i) | next | 1;
546 		next = tmp << (7 - i);
547 	}
548 	pkey[i] = next | 1;
549 
550 	wc_Des_SetKey(&des, pkey, NULL, DES_ENCRYPTION);
551 	wc_Des_EcbEncrypt(&des, cypher, clear, DES_BLOCK_SIZE);
552 
553 	return 0;
554 }
555 #endif /* CONFIG_DES */
556 
557 
aes_encrypt_init(const u8 * key,size_t len)558 void * aes_encrypt_init(const u8 *key, size_t len)
559 {
560 	Aes *aes;
561 	int err;
562 
563 	if (TEST_FAIL())
564 		return NULL;
565 
566 	aes = os_malloc(sizeof(Aes));
567 	if (!aes) {
568 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
569 		return NULL;
570 	}
571 
572 	err = wc_AesSetKey(aes, key, len, NULL, AES_ENCRYPTION);
573 	if (err < 0) {
574 		LOG_WOLF_ERROR_FUNC(wc_AesSetKey, err);
575 		os_free(aes);
576 		return NULL;
577 	}
578 
579 	return aes;
580 }
581 
582 
aes_encrypt(void * ctx,const u8 * plain,u8 * crypt)583 int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
584 {
585 #if defined(HAVE_FIPS) && \
586     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION <= 2))
587 	/* Old FIPS has void return on this API */
588 	wc_AesEncryptDirect(ctx, crypt, plain);
589 #else
590 	int err = wc_AesEncryptDirect(ctx, crypt, plain);
591 
592 	if (err != 0) {
593 		LOG_WOLF_ERROR_FUNC(wc_AesEncryptDirect, err);
594 		return -1;
595 	}
596 #endif
597 	return 0;
598 }
599 
600 
aes_encrypt_deinit(void * ctx)601 void aes_encrypt_deinit(void *ctx)
602 {
603 	os_free(ctx);
604 }
605 
606 
aes_decrypt_init(const u8 * key,size_t len)607 void * aes_decrypt_init(const u8 *key, size_t len)
608 {
609 	Aes *aes;
610 	int err;
611 
612 	if (TEST_FAIL())
613 		return NULL;
614 
615 	aes = os_malloc(sizeof(Aes));
616 	if (!aes) {
617 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
618 		return NULL;
619 	}
620 
621 	err = wc_AesSetKey(aes, key, len, NULL, AES_DECRYPTION);
622 	if (err < 0) {
623 		LOG_WOLF_ERROR_FUNC(wc_AesSetKey, err);
624 		os_free(aes);
625 		return NULL;
626 	}
627 
628 	return aes;
629 }
630 
631 
aes_decrypt(void * ctx,const u8 * crypt,u8 * plain)632 int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
633 {
634 #if defined(HAVE_FIPS) && \
635     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION <= 2))
636 	/* Old FIPS has void return on this API */
637 	wc_AesDecryptDirect(ctx, plain, crypt);
638 #else
639 	int err = wc_AesDecryptDirect(ctx, plain, crypt);
640 
641 	if (err != 0) {
642 		LOG_WOLF_ERROR_FUNC(wc_AesDecryptDirect, err);
643 		return -1;
644 	}
645 #endif
646 	return 0;
647 }
648 
649 
aes_decrypt_deinit(void * ctx)650 void aes_decrypt_deinit(void *ctx)
651 {
652 	os_free(ctx);
653 }
654 
655 
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)656 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
657 {
658 	Aes aes;
659 	int ret;
660 
661 	if (TEST_FAIL())
662 		return -1;
663 
664 	ret = wc_AesSetKey(&aes, key, 16, iv, AES_ENCRYPTION);
665 	if (ret != 0)
666 		return -1;
667 
668 	ret = wc_AesCbcEncrypt(&aes, data, data, data_len);
669 	if (ret != 0)
670 		return -1;
671 	return 0;
672 }
673 
674 
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)675 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
676 {
677 	Aes aes;
678 	int ret;
679 
680 	if (TEST_FAIL())
681 		return -1;
682 
683 	ret = wc_AesSetKey(&aes, key, 16, iv, AES_DECRYPTION);
684 	if (ret != 0)
685 		return -1;
686 
687 	ret = wc_AesCbcDecrypt(&aes, data, data, data_len);
688 	if (ret != 0)
689 		return -1;
690 	return 0;
691 }
692 
693 
694 #ifndef CONFIG_FIPS
695 #ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP
aes_wrap(const u8 * kek,size_t kek_len,int n,const u8 * plain,u8 * cipher)696 int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
697 {
698 #ifdef HAVE_AES_KEYWRAP
699 	int ret;
700 
701 	if (TEST_FAIL())
702 		return -1;
703 
704 	ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8,
705 			    NULL);
706 	return ret != (n + 1) * 8 ? -1 : 0;
707 #else /* HAVE_AES_KEYWRAP */
708 	return -1;
709 #endif /* HAVE_AES_KEYWRAP */
710 }
711 
712 
aes_unwrap(const u8 * kek,size_t kek_len,int n,const u8 * cipher,u8 * plain)713 int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
714 	       u8 *plain)
715 {
716 #ifdef HAVE_AES_KEYWRAP
717 	int ret;
718 
719 	if (TEST_FAIL())
720 		return -1;
721 
722 	ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8,
723 			      NULL);
724 	return ret != n * 8 ? -1 : 0;
725 #else /* HAVE_AES_KEYWRAP */
726 	return -1;
727 #endif /* HAVE_AES_KEYWRAP */
728 }
729 #endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */
730 #endif /* CONFIG_FIPS */
731 
732 
733 #ifndef CONFIG_NO_RC4
rc4_skip(const u8 * key,size_t keylen,size_t skip,u8 * data,size_t data_len)734 int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data,
735 	     size_t data_len)
736 {
737 #ifndef NO_RC4
738 	Arc4 arc4;
739 	unsigned char skip_buf[16];
740 
741 	wc_Arc4SetKey(&arc4, key, keylen);
742 
743 	while (skip >= sizeof(skip_buf)) {
744 		size_t len = skip;
745 
746 		if (len > sizeof(skip_buf))
747 			len = sizeof(skip_buf);
748 		wc_Arc4Process(&arc4, skip_buf, skip_buf, len);
749 		skip -= len;
750 	}
751 
752 	wc_Arc4Process(&arc4, data, data, data_len);
753 
754 	return 0;
755 #else /* NO_RC4 */
756 	return -1;
757 #endif /* NO_RC4 */
758 }
759 #endif /* CONFIG_NO_RC4 */
760 
761 
762 #if defined(EAP_IKEV2) || defined(EAP_IKEV2_DYNAMIC) \
763 		       || defined(EAP_SERVER_IKEV2)
764 union wolfssl_cipher {
765 	Aes aes;
766 	Des3 des3;
767 	Arc4 arc4;
768 };
769 
770 struct crypto_cipher {
771 	enum crypto_cipher_alg alg;
772 	union wolfssl_cipher enc;
773 	union wolfssl_cipher dec;
774 };
775 
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)776 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
777 					  const u8 *iv, const u8 *key,
778 					  size_t key_len)
779 {
780 	struct crypto_cipher *ctx;
781 
782 	ctx = os_zalloc(sizeof(*ctx));
783 	if (!ctx)
784 		return NULL;
785 
786 	switch (alg) {
787 #ifndef CONFIG_NO_RC4
788 #ifndef NO_RC4
789 	case CRYPTO_CIPHER_ALG_RC4:
790 		wc_Arc4SetKey(&ctx->enc.arc4, key, key_len);
791 		wc_Arc4SetKey(&ctx->dec.arc4, key, key_len);
792 		break;
793 #endif /* NO_RC4 */
794 #endif /* CONFIG_NO_RC4 */
795 #ifndef NO_AES
796 	case CRYPTO_CIPHER_ALG_AES:
797 		switch (key_len) {
798 		case 16:
799 		case 24:
800 		case 32:
801 			break;
802 		default:
803 			os_free(ctx);
804 			return NULL;
805 		}
806 		if (wc_AesSetKey(&ctx->enc.aes, key, key_len, iv,
807 				 AES_ENCRYPTION) ||
808 		    wc_AesSetKey(&ctx->dec.aes, key, key_len, iv,
809 				 AES_DECRYPTION)) {
810 			os_free(ctx);
811 			return NULL;
812 		}
813 		break;
814 #endif /* NO_AES */
815 #ifndef NO_DES3
816 	case CRYPTO_CIPHER_ALG_3DES:
817 		if (key_len != DES3_KEYLEN ||
818 		    wc_Des3_SetKey(&ctx->enc.des3, key, iv, DES_ENCRYPTION) ||
819 		    wc_Des3_SetKey(&ctx->dec.des3, key, iv, DES_DECRYPTION)) {
820 			os_free(ctx);
821 			return NULL;
822 		}
823 		break;
824 #endif /* NO_DES3 */
825 	case CRYPTO_CIPHER_ALG_RC2:
826 	case CRYPTO_CIPHER_ALG_DES:
827 	default:
828 		os_free(ctx);
829 		return NULL;
830 	}
831 
832 	ctx->alg = alg;
833 
834 	return ctx;
835 }
836 
837 
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)838 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
839 			  u8 *crypt, size_t len)
840 {
841 	switch (ctx->alg) {
842 #ifndef CONFIG_NO_RC4
843 #ifndef NO_RC4
844 	case CRYPTO_CIPHER_ALG_RC4:
845 		wc_Arc4Process(&ctx->enc.arc4, crypt, plain, len);
846 		return 0;
847 #endif /* NO_RC4 */
848 #endif /* CONFIG_NO_RC4 */
849 #ifndef NO_AES
850 	case CRYPTO_CIPHER_ALG_AES:
851 		if (wc_AesCbcEncrypt(&ctx->enc.aes, crypt, plain, len) != 0)
852 			return -1;
853 		return 0;
854 #endif /* NO_AES */
855 #ifndef NO_DES3
856 	case CRYPTO_CIPHER_ALG_3DES:
857 		if (wc_Des3_CbcEncrypt(&ctx->enc.des3, crypt, plain, len) != 0)
858 			return -1;
859 		return 0;
860 #endif /* NO_DES3 */
861 	default:
862 		return -1;
863 	}
864 	return -1;
865 }
866 
867 
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)868 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
869 			  u8 *plain, size_t len)
870 {
871 	switch (ctx->alg) {
872 #ifndef CONFIG_NO_RC4
873 #ifndef NO_RC4
874 	case CRYPTO_CIPHER_ALG_RC4:
875 		wc_Arc4Process(&ctx->dec.arc4, plain, crypt, len);
876 		return 0;
877 #endif /* NO_RC4 */
878 #endif /* CONFIG_NO_RC4 */
879 #ifndef NO_AES
880 	case CRYPTO_CIPHER_ALG_AES:
881 		if (wc_AesCbcDecrypt(&ctx->dec.aes, plain, crypt, len) != 0)
882 			return -1;
883 		return 0;
884 #endif /* NO_AES */
885 #ifndef NO_DES3
886 	case CRYPTO_CIPHER_ALG_3DES:
887 		if (wc_Des3_CbcDecrypt(&ctx->dec.des3, plain, crypt, len) != 0)
888 			return -1;
889 		return 0;
890 #endif /* NO_DES3 */
891 	default:
892 		return -1;
893 	}
894 	return -1;
895 }
896 
897 
crypto_cipher_deinit(struct crypto_cipher * ctx)898 void crypto_cipher_deinit(struct crypto_cipher *ctx)
899 {
900 	os_free(ctx);
901 }
902 
903 #endif
904 
905 
906 #ifdef CONFIG_WPS
907 
908 static const unsigned char RFC3526_PRIME_1536[] = {
909 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
910 	0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
911 	0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
912 	0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
913 	0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
914 	0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
915 	0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
916 	0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
917 	0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
918 	0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
919 	0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
920 	0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
921 	0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
922 	0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
923 	0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
924 	0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
925 };
926 
927 static const unsigned char RFC3526_GENERATOR_1536[] = {
928 	0x02
929 };
930 
931 #define RFC3526_LEN sizeof(RFC3526_PRIME_1536)
932 
933 
dh5_init(struct wpabuf ** priv,struct wpabuf ** publ)934 void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
935 {
936 	WC_RNG rng;
937 	DhKey *ret = NULL;
938 	DhKey *dh = NULL;
939 	struct wpabuf *privkey = NULL;
940 	struct wpabuf *pubkey = NULL;
941 	word32 priv_sz, pub_sz;
942 
943 	*priv = NULL;
944 	wpabuf_free(*publ);
945 	*publ = NULL;
946 
947 	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
948 	if (!dh)
949 		return NULL;
950 	wc_InitDhKey(dh);
951 
952 	if (wc_InitRng(&rng) != 0) {
953 		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
954 		return NULL;
955 	}
956 
957 	privkey = wpabuf_alloc(RFC3526_LEN);
958 	pubkey = wpabuf_alloc(RFC3526_LEN);
959 	if (!privkey || !pubkey)
960 		goto done;
961 
962 	if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
963 			RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
964 	    != 0)
965 		goto done;
966 
967 	priv_sz = pub_sz = RFC3526_LEN;
968 	if (wc_DhGenerateKeyPair(dh, &rng, wpabuf_mhead(privkey), &priv_sz,
969 				 wpabuf_mhead(pubkey), &pub_sz) != 0)
970 		goto done;
971 
972 	wpabuf_put(privkey, priv_sz);
973 	wpabuf_put(pubkey, pub_sz);
974 
975 	ret = dh;
976 	*priv = privkey;
977 	*publ = pubkey;
978 	dh = NULL;
979 	privkey = NULL;
980 	pubkey = NULL;
981 done:
982 	wpabuf_clear_free(pubkey);
983 	wpabuf_clear_free(privkey);
984 	if (dh) {
985 		wc_FreeDhKey(dh);
986 		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
987 	}
988 	wc_FreeRng(&rng);
989 	return ret;
990 }
991 
992 
993 #ifdef CONFIG_WPS_NFC
994 
dh5_init_fixed(const struct wpabuf * priv,const struct wpabuf * publ)995 void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
996 {
997 	DhKey *ret = NULL;
998 	DhKey *dh;
999 	byte *secret;
1000 	word32 secret_sz;
1001 
1002 	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
1003 	if (!dh)
1004 		return NULL;
1005 	wc_InitDhKey(dh);
1006 
1007 	secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1008 	if (!secret)
1009 		goto done;
1010 
1011 	if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
1012 			RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
1013 	    != 0)
1014 		goto done;
1015 
1016 	if (wc_DhAgree(dh, secret, &secret_sz, wpabuf_head(priv),
1017 		       wpabuf_len(priv), RFC3526_GENERATOR_1536,
1018 		       sizeof(RFC3526_GENERATOR_1536)) != 0)
1019 		goto done;
1020 
1021 	if (secret_sz != wpabuf_len(publ) ||
1022 	    os_memcmp(secret, wpabuf_head(publ), secret_sz) != 0)
1023 		goto done;
1024 
1025 	ret = dh;
1026 	dh = NULL;
1027 done:
1028 	if (dh) {
1029 		wc_FreeDhKey(dh);
1030 		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1031 	}
1032 	XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1033 	return ret;
1034 }
1035 
1036 #endif /* CONFIG_WPS_NFC */
1037 
1038 
dh5_derive_shared(void * ctx,const struct wpabuf * peer_public,const struct wpabuf * own_private)1039 struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
1040 				  const struct wpabuf *own_private)
1041 {
1042 	struct wpabuf *ret = NULL;
1043 	struct wpabuf *secret;
1044 	word32 secret_sz;
1045 
1046 	secret = wpabuf_alloc(RFC3526_LEN);
1047 	if (!secret)
1048 		goto done;
1049 
1050 	if (wc_DhAgree(ctx, wpabuf_mhead(secret), &secret_sz,
1051 		       wpabuf_head(own_private), wpabuf_len(own_private),
1052 		       wpabuf_head(peer_public), wpabuf_len(peer_public)) != 0)
1053 		goto done;
1054 
1055 	wpabuf_put(secret, secret_sz);
1056 
1057 	ret = secret;
1058 	secret = NULL;
1059 done:
1060 	wpabuf_clear_free(secret);
1061 	return ret;
1062 }
1063 
1064 
dh5_free(void * ctx)1065 void dh5_free(void *ctx)
1066 {
1067 	if (!ctx)
1068 		return;
1069 
1070 	wc_FreeDhKey(ctx);
1071 	XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1072 }
1073 
1074 #endif /* CONFIG_WPS */
1075 
1076 
crypto_dh_init(u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)1077 int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
1078 		   u8 *pubkey)
1079 {
1080 	int ret = -1;
1081 	WC_RNG rng;
1082 	DhKey *dh = NULL;
1083 	word32 priv_sz, pub_sz;
1084 
1085 	if (TEST_FAIL())
1086 		return -1;
1087 
1088 	dh = os_malloc(sizeof(DhKey));
1089 	if (!dh)
1090 		return -1;
1091 	wc_InitDhKey(dh);
1092 
1093 	if (wc_InitRng(&rng) != 0) {
1094 		os_free(dh);
1095 		return -1;
1096 	}
1097 
1098 	if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
1099 		goto done;
1100 
1101 	priv_sz = pub_sz = prime_len;
1102 	if (wc_DhGenerateKeyPair(dh, &rng, privkey, &priv_sz, pubkey, &pub_sz)
1103 	    != 0)
1104 		goto done;
1105 
1106 	if (priv_sz < prime_len) {
1107 		size_t pad_sz = prime_len - priv_sz;
1108 
1109 		os_memmove(privkey + pad_sz, privkey, priv_sz);
1110 		os_memset(privkey, 0, pad_sz);
1111 	}
1112 
1113 	if (pub_sz < prime_len) {
1114 		size_t pad_sz = prime_len - pub_sz;
1115 
1116 		os_memmove(pubkey + pad_sz, pubkey, pub_sz);
1117 		os_memset(pubkey, 0, pad_sz);
1118 	}
1119 	ret = 0;
1120 done:
1121 	wc_FreeDhKey(dh);
1122 	os_free(dh);
1123 	wc_FreeRng(&rng);
1124 	return ret;
1125 }
1126 
1127 
crypto_dh_derive_secret(u8 generator,const u8 * prime,size_t prime_len,const u8 * order,size_t order_len,const u8 * privkey,size_t privkey_len,const u8 * pubkey,size_t pubkey_len,u8 * secret,size_t * len)1128 int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len,
1129 			    const u8 *order, size_t order_len,
1130 			    const u8 *privkey, size_t privkey_len,
1131 			    const u8 *pubkey, size_t pubkey_len,
1132 			    u8 *secret, size_t *len)
1133 {
1134 	int ret = -1;
1135 	DhKey *dh;
1136 	word32 secret_sz;
1137 
1138 	dh = os_malloc(sizeof(DhKey));
1139 	if (!dh)
1140 		return -1;
1141 	wc_InitDhKey(dh);
1142 
1143 	if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
1144 		goto done;
1145 
1146 	if (wc_DhAgree(dh, secret, &secret_sz, privkey, privkey_len, pubkey,
1147 		       pubkey_len) != 0)
1148 		goto done;
1149 
1150 	*len = secret_sz;
1151 	ret = 0;
1152 done:
1153 	wc_FreeDhKey(dh);
1154 	os_free(dh);
1155 	return ret;
1156 }
1157 
1158 
1159 #ifdef CONFIG_FIPS
crypto_get_random(void * buf,size_t len)1160 int crypto_get_random(void *buf, size_t len)
1161 {
1162 	int ret = 0;
1163 	WC_RNG rng;
1164 
1165 	if (wc_InitRng(&rng) != 0)
1166 		return -1;
1167 	if (wc_RNG_GenerateBlock(&rng, buf, len) != 0)
1168 		ret = -1;
1169 	wc_FreeRng(&rng);
1170 	return ret;
1171 }
1172 #endif /* CONFIG_FIPS */
1173 
1174 
1175 #if defined(EAP_PWD) || defined(EAP_SERVER_PWD)
1176 struct crypto_hash {
1177 	Hmac hmac;
1178 	int size;
1179 };
1180 
1181 
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)1182 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
1183 				      size_t key_len)
1184 {
1185 	struct crypto_hash *ret = NULL;
1186 	struct crypto_hash *hash;
1187 	int type;
1188 
1189 	hash = os_zalloc(sizeof(*hash));
1190 	if (!hash)
1191 		goto done;
1192 
1193 	switch (alg) {
1194 #ifndef NO_MD5
1195 	case CRYPTO_HASH_ALG_HMAC_MD5:
1196 		hash->size = 16;
1197 		type = WC_MD5;
1198 		break;
1199 #endif /* NO_MD5 */
1200 #ifndef NO_SHA
1201 	case CRYPTO_HASH_ALG_HMAC_SHA1:
1202 		type = WC_SHA;
1203 		hash->size = 20;
1204 		break;
1205 #endif /* NO_SHA */
1206 #ifdef CONFIG_SHA256
1207 #ifndef NO_SHA256
1208 	case CRYPTO_HASH_ALG_HMAC_SHA256:
1209 		type = WC_SHA256;
1210 		hash->size = 32;
1211 		break;
1212 #endif /* NO_SHA256 */
1213 #endif /* CONFIG_SHA256 */
1214 	default:
1215 		goto done;
1216 	}
1217 
1218 	if (wc_HmacInit(&hash->hmac, NULL, INVALID_DEVID) != 0 ||
1219 	    wc_HmacSetKey(&hash->hmac, type, key, key_len) != 0)
1220 		goto done;
1221 
1222 	ret = hash;
1223 	hash = NULL;
1224 done:
1225 	os_free(hash);
1226 	return ret;
1227 }
1228 
1229 
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)1230 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
1231 {
1232 	if (!ctx)
1233 		return;
1234 	wc_HmacUpdate(&ctx->hmac, data, len);
1235 }
1236 
1237 
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)1238 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
1239 {
1240 	int ret = 0;
1241 
1242 	if (!ctx)
1243 		return -2;
1244 
1245 	if (!mac || !len)
1246 		goto done;
1247 
1248 	if (wc_HmacFinal(&ctx->hmac, mac) != 0) {
1249 		ret = -1;
1250 		goto done;
1251 	}
1252 
1253 	*len = ctx->size;
1254 	ret = 0;
1255 done:
1256 	bin_clear_free(ctx, sizeof(*ctx));
1257 	if (TEST_FAIL())
1258 		return -1;
1259 	return ret;
1260 }
1261 
1262 #endif
1263 
1264 
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1265 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
1266 		     const u8 *addr[], const size_t *len, u8 *mac)
1267 {
1268 	Cmac cmac;
1269 	size_t i;
1270 	word32 sz;
1271 
1272 	if (TEST_FAIL())
1273 		return -1;
1274 
1275 	if (wc_InitCmac(&cmac, key, key_len, WC_CMAC_AES, NULL) != 0)
1276 		return -1;
1277 
1278 	for (i = 0; i < num_elem; i++)
1279 		if (wc_CmacUpdate(&cmac, addr[i], len[i]) != 0)
1280 			return -1;
1281 
1282 	sz = AES_BLOCK_SIZE;
1283 	if (wc_CmacFinal(&cmac, mac, &sz) != 0 || sz != AES_BLOCK_SIZE)
1284 		return -1;
1285 
1286 	return 0;
1287 }
1288 
1289 
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1290 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1291 			 const u8 *addr[], const size_t *len, u8 *mac)
1292 {
1293 	return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1294 }
1295 
1296 
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1297 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1298 {
1299 	return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1300 }
1301 
1302 
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1303 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1304 {
1305 	return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1306 }
1307 
1308 
crypto_bignum_init(void)1309 struct crypto_bignum * crypto_bignum_init(void)
1310 {
1311 	mp_int *a;
1312 
1313 	if (TEST_FAIL())
1314 		return NULL;
1315 
1316 	a = os_malloc(sizeof(*a));
1317 	if (!a || mp_init(a) != MP_OKAY) {
1318 		os_free(a);
1319 		a = NULL;
1320 	}
1321 
1322 	return (struct crypto_bignum *) a;
1323 }
1324 
1325 
crypto_bignum_init_set(const u8 * buf,size_t len)1326 struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
1327 {
1328 	mp_int *a;
1329 
1330 	if (TEST_FAIL())
1331 		return NULL;
1332 
1333 	a = (mp_int *) crypto_bignum_init();
1334 	if (!a)
1335 		return NULL;
1336 
1337 	if (mp_read_unsigned_bin(a, buf, len) != MP_OKAY) {
1338 		os_free(a);
1339 		a = NULL;
1340 	}
1341 
1342 	return (struct crypto_bignum *) a;
1343 }
1344 
1345 
crypto_bignum_init_uint(unsigned int val)1346 struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
1347 {
1348 	mp_int *a;
1349 
1350 	if (TEST_FAIL())
1351 		return NULL;
1352 
1353 	a = (mp_int *) crypto_bignum_init();
1354 	if (!a)
1355 		return NULL;
1356 
1357 	if (mp_set_int(a, val) != MP_OKAY) {
1358 		os_free(a);
1359 		a = NULL;
1360 	}
1361 
1362 	return (struct crypto_bignum *) a;
1363 }
1364 
1365 
crypto_bignum_deinit(struct crypto_bignum * n,int clear)1366 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1367 {
1368 	if (!n)
1369 		return;
1370 
1371 	if (clear)
1372 		mp_forcezero((mp_int *) n);
1373 	mp_clear((mp_int *) n);
1374 	os_free((mp_int *) n);
1375 }
1376 
1377 
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)1378 int crypto_bignum_to_bin(const struct crypto_bignum *a,
1379 			 u8 *buf, size_t buflen, size_t padlen)
1380 {
1381 	int num_bytes, offset;
1382 
1383 	if (TEST_FAIL())
1384 		return -1;
1385 
1386 	if (padlen > buflen)
1387 		return -1;
1388 
1389 	num_bytes = (mp_count_bits((mp_int *) a) + 7) / 8;
1390 	if ((size_t) num_bytes > buflen)
1391 		return -1;
1392 	if (padlen > (size_t) num_bytes)
1393 		offset = padlen - num_bytes;
1394 	else
1395 		offset = 0;
1396 
1397 	os_memset(buf, 0, offset);
1398 	mp_to_unsigned_bin((mp_int *) a, buf + offset);
1399 
1400 	return num_bytes + offset;
1401 }
1402 
1403 
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)1404 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
1405 {
1406 	int ret = 0;
1407 	WC_RNG rng;
1408 	size_t len;
1409 	u8 *buf;
1410 
1411 	if (TEST_FAIL())
1412 		return -1;
1413 	if (wc_InitRng(&rng) != 0)
1414 		return -1;
1415 	len = (mp_count_bits((mp_int *) m) + 7) / 8;
1416 	buf = os_malloc(len);
1417 	if (!buf || wc_RNG_GenerateBlock(&rng, buf, len) != 0 ||
1418 	    mp_read_unsigned_bin((mp_int *) r, buf, len) != MP_OKAY ||
1419 	    mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0)
1420 		ret = -1;
1421 	wc_FreeRng(&rng);
1422 	bin_clear_free(buf, len);
1423 	return ret;
1424 }
1425 
1426 
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)1427 int crypto_bignum_add(const struct crypto_bignum *a,
1428 		      const struct crypto_bignum *b,
1429 		      struct crypto_bignum *r)
1430 {
1431 	return mp_add((mp_int *) a, (mp_int *) b,
1432 		      (mp_int *) r) == MP_OKAY ? 0 : -1;
1433 }
1434 
1435 
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)1436 int crypto_bignum_mod(const struct crypto_bignum *a,
1437 		      const struct crypto_bignum *m,
1438 		      struct crypto_bignum *r)
1439 {
1440 	return mp_mod((mp_int *) a, (mp_int *) m,
1441 		      (mp_int *) r) == MP_OKAY ? 0 : -1;
1442 }
1443 
1444 
crypto_bignum_exptmod(const struct crypto_bignum * b,const struct crypto_bignum * e,const struct crypto_bignum * m,struct crypto_bignum * r)1445 int crypto_bignum_exptmod(const struct crypto_bignum *b,
1446 			  const struct crypto_bignum *e,
1447 			  const struct crypto_bignum *m,
1448 			  struct crypto_bignum *r)
1449 {
1450 	if (TEST_FAIL())
1451 		return -1;
1452 
1453 	return mp_exptmod((mp_int *) b, (mp_int *) e, (mp_int *) m,
1454 			  (mp_int *) r) == MP_OKAY ?  0 : -1;
1455 }
1456 
1457 
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)1458 int crypto_bignum_inverse(const struct crypto_bignum *a,
1459 			  const struct crypto_bignum *m,
1460 			  struct crypto_bignum *r)
1461 {
1462 	if (TEST_FAIL())
1463 		return -1;
1464 
1465 	return mp_invmod((mp_int *) a, (mp_int *) m,
1466 			 (mp_int *) r) == MP_OKAY ? 0 : -1;
1467 }
1468 
1469 
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)1470 int crypto_bignum_sub(const struct crypto_bignum *a,
1471 		      const struct crypto_bignum *b,
1472 		      struct crypto_bignum *r)
1473 {
1474 	if (TEST_FAIL())
1475 		return -1;
1476 
1477 	return mp_sub((mp_int *) a, (mp_int *) b,
1478 		      (mp_int *) r) == MP_OKAY ? 0 : -1;
1479 }
1480 
1481 
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * d)1482 int crypto_bignum_div(const struct crypto_bignum *a,
1483 		      const struct crypto_bignum *b,
1484 		      struct crypto_bignum *d)
1485 {
1486 	if (TEST_FAIL())
1487 		return -1;
1488 
1489 	return mp_div((mp_int *) a, (mp_int *) b, (mp_int *) d,
1490 		      NULL) == MP_OKAY ? 0 : -1;
1491 }
1492 
1493 
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)1494 int crypto_bignum_addmod(const struct crypto_bignum *a,
1495 			 const struct crypto_bignum *b,
1496 			 const struct crypto_bignum *c,
1497 			 struct crypto_bignum *d)
1498 {
1499 	if (TEST_FAIL())
1500 		return -1;
1501 
1502 	return mp_addmod((mp_int *) a, (mp_int *) b, (mp_int *) c,
1503 			 (mp_int *) d) == MP_OKAY ?  0 : -1;
1504 }
1505 
1506 
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * m,struct crypto_bignum * d)1507 int crypto_bignum_mulmod(const struct crypto_bignum *a,
1508 			 const struct crypto_bignum *b,
1509 			 const struct crypto_bignum *m,
1510 			 struct crypto_bignum *d)
1511 {
1512 	if (TEST_FAIL())
1513 		return -1;
1514 
1515 	return mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) m,
1516 			 (mp_int *) d) == MP_OKAY ?  0 : -1;
1517 }
1518 
1519 
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1520 int crypto_bignum_sqrmod(const struct crypto_bignum *a,
1521 			 const struct crypto_bignum *b,
1522 			 struct crypto_bignum *c)
1523 {
1524 	if (TEST_FAIL())
1525 		return -1;
1526 
1527 	return mp_sqrmod((mp_int *) a, (mp_int *) b,
1528 			 (mp_int *) c) == MP_OKAY ?  0 : -1;
1529 }
1530 
1531 
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)1532 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1533 			 struct crypto_bignum *r)
1534 {
1535 	if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1536 		return -1;
1537 	mp_rshb((mp_int *) r, n);
1538 	return 0;
1539 }
1540 
1541 
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)1542 int crypto_bignum_cmp(const struct crypto_bignum *a,
1543 		      const struct crypto_bignum *b)
1544 {
1545 	return mp_cmp((mp_int *) a, (mp_int *) b);
1546 }
1547 
1548 
crypto_bignum_is_zero(const struct crypto_bignum * a)1549 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1550 {
1551 	return mp_iszero((mp_int *) a);
1552 }
1553 
1554 
crypto_bignum_is_one(const struct crypto_bignum * a)1555 int crypto_bignum_is_one(const struct crypto_bignum *a)
1556 {
1557 	return mp_isone((const mp_int *) a);
1558 }
1559 
crypto_bignum_is_odd(const struct crypto_bignum * a)1560 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1561 {
1562 	return mp_isodd((mp_int *) a);
1563 }
1564 
1565 
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)1566 int crypto_bignum_legendre(const struct crypto_bignum *a,
1567 			   const struct crypto_bignum *p)
1568 {
1569 	mp_int t;
1570 	int ret;
1571 	int res = -2;
1572 
1573 	if (TEST_FAIL())
1574 		return -2;
1575 
1576 	if (mp_init(&t) != MP_OKAY)
1577 		return -2;
1578 
1579 	/* t = (p-1) / 2 */
1580 	ret = mp_sub_d((mp_int *) p, 1, &t);
1581 	if (ret == MP_OKAY)
1582 		mp_rshb(&t, 1);
1583 	if (ret == MP_OKAY)
1584 		ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1585 	if (ret == MP_OKAY) {
1586 		if (mp_isone(&t))
1587 			res = 1;
1588 		else if (mp_iszero(&t))
1589 			res = 0;
1590 		else
1591 			res = -1;
1592 	}
1593 
1594 	mp_clear(&t);
1595 	return res;
1596 }
1597 
1598 
1599 #ifdef CONFIG_ECC
1600 
crypto_ec_group_2_id(int group)1601 static int crypto_ec_group_2_id(int group)
1602 {
1603 	switch (group) {
1604 	case 19:
1605 		return ECC_SECP256R1;
1606 	case 20:
1607 		return ECC_SECP384R1;
1608 	case 21:
1609 		return ECC_SECP521R1;
1610 	case 25:
1611 		return ECC_SECP192R1;
1612 	case 26:
1613 		return ECC_SECP224R1;
1614 #ifdef HAVE_ECC_BRAINPOOL
1615 	case 27:
1616 		return ECC_BRAINPOOLP224R1;
1617 	case 28:
1618 		return ECC_BRAINPOOLP256R1;
1619 	case 29:
1620 		return ECC_BRAINPOOLP384R1;
1621 	case 30:
1622 		return ECC_BRAINPOOLP512R1;
1623 #endif /* HAVE_ECC_BRAINPOOL */
1624 	default:
1625 		LOG_WOLF_ERROR_VA("Unsupported curve (id=%d) in EC key", group);
1626 		return ECC_CURVE_INVALID;
1627 	}
1628 }
1629 
1630 
1631 int ecc_map(ecc_point *, mp_int *, mp_digit);
1632 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1633 			     mp_int *a, mp_int *modulus, mp_digit mp);
1634 
1635 struct crypto_ec {
1636 	ecc_key *key;
1637 #ifdef CONFIG_DPP
1638 	ecc_point *g; /* Only used in DPP for now */
1639 #endif /* CONFIG_DPP */
1640 	mp_int a;
1641 	mp_int prime;
1642 	mp_int order;
1643 	mp_digit mont_b;
1644 	mp_int b;
1645 	int curve_id;
1646 	bool own_key; /* Should we free the `key` */
1647 };
1648 
1649 
crypto_ec_init(int group)1650 struct crypto_ec * crypto_ec_init(int group)
1651 {
1652 	int built = 0;
1653 	struct crypto_ec *e;
1654 	int curve_id = crypto_ec_group_2_id(group);
1655 	int err;
1656 
1657 	if (curve_id == ECC_CURVE_INVALID) {
1658 		LOG_INVALID_PARAMETERS();
1659 		return NULL;
1660 	}
1661 
1662 	e = os_zalloc(sizeof(*e));
1663 	if (!e) {
1664 		LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
1665 		return NULL;
1666 	}
1667 
1668 	e->curve_id = curve_id;
1669 	e->own_key = true;
1670 	e->key = ecc_key_init();
1671 	if (!e->key) {
1672 		LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init);
1673 		goto done;
1674 	}
1675 
1676 	err = wc_ecc_set_curve(e->key, 0, curve_id);
1677 	if (err != 0) {
1678 		LOG_WOLF_ERROR_FUNC(wc_ecc_set_curve, err);
1679 		goto done;
1680 	}
1681 #ifdef CONFIG_DPP
1682 	e->g = wc_ecc_new_point();
1683 	if (!e->g) {
1684 		LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
1685 		goto done;
1686 	}
1687 #ifdef CONFIG_FIPS
1688 	/* Setup generator manually in FIPS mode */
1689 	if (!e->key->dp) {
1690 		LOG_WOLF_ERROR_FUNC_NULL(e->key->dp);
1691 		goto done;
1692 	}
1693 	err = mp_read_radix(e->g->x, e->key->dp->Gx, MP_RADIX_HEX);
1694 	if (err != MP_OKAY) {
1695 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1696 		goto done;
1697 	}
1698 	err = mp_read_radix(e->g->y, e->key->dp->Gy, MP_RADIX_HEX);
1699 	if (err != MP_OKAY) {
1700 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1701 		goto done;
1702 	}
1703 	err = mp_set(e->g->z, 1);
1704 	if (err != MP_OKAY) {
1705 		LOG_WOLF_ERROR_FUNC(mp_set, err);
1706 		goto done;
1707 	}
1708 #else /* CONFIG_FIPS */
1709 	err = wc_ecc_get_generator(e->g, wc_ecc_get_curve_idx(curve_id));
1710 	if (err != MP_OKAY) {
1711 		LOG_WOLF_ERROR_FUNC(wc_ecc_get_generator, err);
1712 		goto done;
1713 	}
1714 #endif /* CONFIG_FIPS */
1715 #endif /* CONFIG_DPP */
1716 	err = mp_init_multi(&e->a, &e->prime, &e->order, &e->b, NULL, NULL);
1717 	if (err != MP_OKAY) {
1718 		LOG_WOLF_ERROR_FUNC(mp_init_multi, err);
1719 		goto done;
1720 	}
1721 	err = mp_read_radix(&e->a, e->key->dp->Af, 16);
1722 	if (err != MP_OKAY) {
1723 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1724 		goto done;
1725 	}
1726 	err = mp_read_radix(&e->b, e->key->dp->Bf, 16);
1727 	if (err != MP_OKAY) {
1728 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1729 		goto done;
1730 	}
1731 	err = mp_read_radix(&e->prime, e->key->dp->prime, 16);
1732 	if (err != MP_OKAY) {
1733 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1734 		goto done;
1735 	}
1736 	err = mp_read_radix(&e->order, e->key->dp->order, 16);
1737 	if (err != MP_OKAY) {
1738 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1739 		goto done;
1740 	}
1741 	err = mp_montgomery_setup(&e->prime, &e->mont_b);
1742 	if (err != MP_OKAY) {
1743 		LOG_WOLF_ERROR_FUNC(mp_montgomery_setup, err);
1744 		goto done;
1745 	}
1746 
1747 	built = 1;
1748 done:
1749 	if (!built) {
1750 		crypto_ec_deinit(e);
1751 		e = NULL;
1752 	}
1753 	return e;
1754 }
1755 
1756 
crypto_ec_deinit(struct crypto_ec * e)1757 void crypto_ec_deinit(struct crypto_ec* e)
1758 {
1759 	if (!e)
1760 		return;
1761 
1762 	mp_clear(&e->b);
1763 	mp_clear(&e->order);
1764 	mp_clear(&e->prime);
1765 	mp_clear(&e->a);
1766 #ifdef CONFIG_DPP
1767 	wc_ecc_del_point(e->g);
1768 #endif /* CONFIG_DPP */
1769 	if (e->own_key)
1770 		ecc_key_deinit(e->key);
1771 	os_free(e);
1772 }
1773 
1774 
crypto_ec_point_init(struct crypto_ec * e)1775 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1776 {
1777 	if (TEST_FAIL())
1778 		return NULL;
1779 	if (!e)
1780 		return NULL;
1781 	return (struct crypto_ec_point *) wc_ecc_new_point();
1782 }
1783 
1784 
crypto_ec_prime_len(struct crypto_ec * e)1785 size_t crypto_ec_prime_len(struct crypto_ec *e)
1786 {
1787 	return (mp_count_bits(&e->prime) + 7) / 8;
1788 }
1789 
1790 
crypto_ec_prime_len_bits(struct crypto_ec * e)1791 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1792 {
1793 	return mp_count_bits(&e->prime);
1794 }
1795 
1796 
crypto_ec_order_len(struct crypto_ec * e)1797 size_t crypto_ec_order_len(struct crypto_ec *e)
1798 {
1799 	return (mp_count_bits(&e->order) + 7) / 8;
1800 }
1801 
1802 
crypto_ec_get_prime(struct crypto_ec * e)1803 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1804 {
1805 	return (const struct crypto_bignum *) &e->prime;
1806 }
1807 
1808 
crypto_ec_get_order(struct crypto_ec * e)1809 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1810 {
1811 	return (const struct crypto_bignum *) &e->order;
1812 }
1813 
1814 
crypto_ec_get_a(struct crypto_ec * e)1815 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1816 {
1817 	return (const struct crypto_bignum *) &e->a;
1818 }
1819 
1820 
crypto_ec_get_b(struct crypto_ec * e)1821 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1822 {
1823 	return (const struct crypto_bignum *) &e->b;
1824 }
1825 
1826 
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)1827 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1828 {
1829 	ecc_point *point = (ecc_point *) p;
1830 
1831 	if (!p)
1832 		return;
1833 
1834 	if (clear) {
1835 #ifdef CONFIG_FIPS
1836 		mp_forcezero(point->x);
1837 		mp_forcezero(point->y);
1838 		mp_forcezero(point->z);
1839 #else /* CONFIG_FIPS */
1840 		wc_ecc_forcezero_point(point);
1841 #endif /* CONFIG_FIPS */
1842 	}
1843 	wc_ecc_del_point(point);
1844 }
1845 
1846 
1847 #ifdef CONFIG_DPP
crypto_ec_get_generator(struct crypto_ec * e)1848 const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
1849 {
1850 	return (const struct crypto_ec_point *) e->g;
1851 }
1852 #endif /* CONFIG_DPP */
1853 
1854 
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)1855 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1856 		      struct crypto_bignum *x)
1857 {
1858 	return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1859 }
1860 
1861 
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)1862 int crypto_ec_point_to_bin(struct crypto_ec *e,
1863 			   const struct crypto_ec_point *point, u8 *x, u8 *y)
1864 {
1865 	ecc_point *p = (ecc_point *) point;
1866 	int len;
1867 	int err;
1868 
1869 	if (TEST_FAIL())
1870 		return -1;
1871 
1872 	if (!mp_isone(p->z)) {
1873 		err = ecc_map(p, &e->prime, e->mont_b);
1874 		if (err != MP_OKAY) {
1875 			LOG_WOLF_ERROR_FUNC(ecc_map, err);
1876 			return -1;
1877 		}
1878 	}
1879 
1880 	len = wc_ecc_get_curve_size_from_id(e->curve_id);
1881 	if (len <= 0) {
1882 		LOG_WOLF_ERROR_FUNC(wc_ecc_get_curve_size_from_id, len);
1883 		LOG_WOLF_ERROR_VA("wc_ecc_get_curve_size_from_id error for curve_id %d", e->curve_id);
1884 		return -1;
1885 	}
1886 
1887 	if (x) {
1888 		if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1889 					 (size_t) len, (size_t) len) <= 0) {
1890 			LOG_WOLF_ERROR_FUNC(crypto_bignum_to_bin, -1);
1891 			return -1;
1892 		}
1893 	}
1894 
1895 	if (y) {
1896 		if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1897 					 (size_t) len, (size_t) len) <= 0) {
1898 			LOG_WOLF_ERROR_FUNC(crypto_bignum_to_bin, -1);
1899 			return -1;
1900 		}
1901 	}
1902 
1903 	return 0;
1904 }
1905 
1906 
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)1907 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1908 						  const u8 *val)
1909 {
1910 	ecc_point *point = NULL;
1911 	int loaded = 0;
1912 
1913 	if (TEST_FAIL())
1914 		return NULL;
1915 
1916 	point = wc_ecc_new_point();
1917 	if (!point)
1918 		goto done;
1919 
1920 	if (mp_read_unsigned_bin(point->x, val, e->key->dp->size) != MP_OKAY)
1921 		goto done;
1922 	val += e->key->dp->size;
1923 	if (mp_read_unsigned_bin(point->y, val, e->key->dp->size) != MP_OKAY)
1924 		goto done;
1925 	mp_set(point->z, 1);
1926 
1927 	loaded = 1;
1928 done:
1929 	if (!loaded) {
1930 		wc_ecc_del_point(point);
1931 		point = NULL;
1932 	}
1933 	return (struct crypto_ec_point *) point;
1934 }
1935 
1936 
crypto_ec_point_add(struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b,struct crypto_ec_point * c)1937 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1938 			const struct crypto_ec_point *b,
1939 			struct crypto_ec_point *c)
1940 {
1941 	mp_int mu;
1942 	ecc_point *ta = NULL, *tb = NULL;
1943 	ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1944 	mp_int *modulus = &e->prime;
1945 	int ret;
1946 
1947 	if (TEST_FAIL())
1948 		return -1;
1949 
1950 	ret = mp_init(&mu);
1951 	if (ret != MP_OKAY)
1952 		return -1;
1953 
1954 	ret = mp_montgomery_calc_normalization(&mu, modulus);
1955 	if (ret != MP_OKAY) {
1956 		mp_clear(&mu);
1957 		return -1;
1958 	}
1959 
1960 	if (!mp_isone(&mu)) {
1961 		ta = wc_ecc_new_point();
1962 		if (!ta) {
1963 			mp_clear(&mu);
1964 			return -1;
1965 		}
1966 		tb = wc_ecc_new_point();
1967 		if (!tb) {
1968 			wc_ecc_del_point(ta);
1969 			mp_clear(&mu);
1970 			return -1;
1971 		}
1972 
1973 		if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1974 		    mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1975 		    mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1976 		    mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1977 		    mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1978 		    mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1979 			ret = -1;
1980 			goto end;
1981 		}
1982 		pa = ta;
1983 		pb = tb;
1984 	}
1985 
1986 	ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1987 				       &e->prime, e->mont_b);
1988 	if (ret != 0) {
1989 		ret = -1;
1990 		goto end;
1991 	}
1992 
1993 	if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1994 		ret = -1;
1995 	else
1996 		ret = 0;
1997 end:
1998 	wc_ecc_del_point(tb);
1999 	wc_ecc_del_point(ta);
2000 	mp_clear(&mu);
2001 	return ret;
2002 }
2003 
2004 
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)2005 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
2006 			const struct crypto_bignum *b,
2007 			struct crypto_ec_point *res)
2008 {
2009 	int ret;
2010 
2011 	if (TEST_FAIL())
2012 		return -1;
2013 
2014 	ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
2015 			    &e->a, &e->prime, 1);
2016 	return ret == 0 ? 0 : -1;
2017 }
2018 
2019 
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)2020 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
2021 {
2022 	ecc_point *point = (ecc_point *) p;
2023 
2024 	if (TEST_FAIL())
2025 		return -1;
2026 
2027 	if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
2028 		return -1;
2029 
2030 	return 0;
2031 }
2032 
2033 
2034 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)2035 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
2036 			      const struct crypto_bignum *x)
2037 {
2038 	mp_int *y2;
2039 
2040 	if (TEST_FAIL())
2041 		return NULL;
2042 
2043 	/* y^2 = x^3 + ax + b = (x^2 + a)x + b */
2044 	y2 = (mp_int *) crypto_bignum_init();
2045 	if (!y2 ||
2046 	    mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
2047 	    mp_addmod(y2, &e->a, &e->prime, y2) != 0 ||
2048 	    mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
2049 	    mp_addmod(y2, &e->b, &e->prime, y2) != 0) {
2050 		mp_clear(y2);
2051 		os_free(y2);
2052 		y2 = NULL;
2053 	}
2054 
2055 	return (struct crypto_bignum *) y2;
2056 }
2057 
2058 
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)2059 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
2060 				   const struct crypto_ec_point *p)
2061 {
2062 	return wc_ecc_point_is_at_infinity((ecc_point *) p);
2063 }
2064 
2065 
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)2066 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
2067 				const struct crypto_ec_point *p)
2068 {
2069 	return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
2070 		MP_OKAY;
2071 }
2072 
2073 
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)2074 int crypto_ec_point_cmp(const struct crypto_ec *e,
2075 			const struct crypto_ec_point *a,
2076 			const struct crypto_ec_point *b)
2077 {
2078 	return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
2079 }
2080 
2081 struct crypto_ec_key {
2082 	ecc_key *eckey;
2083 	WC_RNG *rng; /* Needs to be initialized before use.
2084 		      * *NOT* initialized in crypto_ec_key_init */
2085 };
2086 
2087 
2088 struct crypto_ecdh {
2089 	struct crypto_ec *ec;
2090 	WC_RNG *rng;
2091 };
2092 
_crypto_ecdh_init(int group)2093 static struct crypto_ecdh * _crypto_ecdh_init(int group)
2094 {
2095 	struct crypto_ecdh *ecdh = NULL;
2096 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2097 	int ret;
2098 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2099 
2100 	ecdh = os_zalloc(sizeof(*ecdh));
2101 	if (!ecdh) {
2102 		LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
2103 		return NULL;
2104 	}
2105 
2106 	ecdh->rng = wc_rng_init();
2107 	if (!ecdh->rng) {
2108 		LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
2109 		goto fail;
2110 	}
2111 
2112 	ecdh->ec = crypto_ec_init(group);
2113 	if (!ecdh->ec) {
2114 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_init);
2115 		goto fail;
2116 	}
2117 
2118 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2119 	ret = wc_ecc_set_rng(ecdh->ec->key, ecdh->rng);
2120 	if (ret != 0) {
2121 		LOG_WOLF_ERROR_FUNC(wc_ecc_set_rng, ret);
2122 		goto fail;
2123 	}
2124 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2125 
2126 	return ecdh;
2127 fail:
2128 	crypto_ecdh_deinit(ecdh);
2129 	return NULL;
2130 }
2131 
2132 
crypto_ecdh_init(int group)2133 struct crypto_ecdh * crypto_ecdh_init(int group)
2134 {
2135 	struct crypto_ecdh *ret = NULL;
2136 	int err;
2137 
2138 	ret = _crypto_ecdh_init(group);
2139 
2140 	if (!ret) {
2141 		LOG_WOLF_ERROR_FUNC_NULL(_crypto_ecdh_init);
2142 		return NULL;
2143 	}
2144 
2145 	err = wc_ecc_make_key_ex(ret->rng, 0, ret->ec->key,
2146 				 crypto_ec_group_2_id(group));
2147 	if (err != MP_OKAY) {
2148 		LOG_WOLF_ERROR_FUNC(wc_ecc_make_key_ex, err);
2149 		crypto_ecdh_deinit(ret);
2150 		ret = NULL;
2151 	}
2152 
2153 	return ret;
2154 }
2155 
2156 
crypto_ecdh_init2(int group,struct crypto_ec_key * own_key)2157 struct crypto_ecdh * crypto_ecdh_init2(int group, struct crypto_ec_key *own_key)
2158 {
2159 	struct crypto_ecdh *ret = NULL;
2160 
2161 	if (!own_key || crypto_ec_key_group(own_key) != group) {
2162 		LOG_INVALID_PARAMETERS();
2163 		return NULL;
2164 	}
2165 
2166 	ret = _crypto_ecdh_init(group);
2167 	if (ret) {
2168 		/* Already init'ed to the right group. Enough to substitute the
2169 		 * key. */
2170 		ecc_key_deinit(ret->ec->key);
2171 		ret->ec->key = own_key->eckey;
2172 		ret->ec->own_key = false;
2173 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2174 		if (!ret->ec->key->rng) {
2175 			int err = wc_ecc_set_rng(ret->ec->key, ret->rng);
2176 
2177 			if (err != 0)
2178 				LOG_WOLF_ERROR_FUNC(wc_ecc_set_rng, err);
2179 		}
2180 #endif /* ECC_TIMING_RESISTANT && !CONFIG_FIPS */
2181 	}
2182 
2183 	return ret;
2184 }
2185 
2186 
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)2187 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
2188 {
2189 	if (ecdh) {
2190 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2191 		/* Disassociate the rng */
2192 		if (ecdh->ec && ecdh->ec->key &&
2193 		    ecdh->ec->key->rng == ecdh->rng)
2194 			(void) wc_ecc_set_rng(ecdh->ec->key, NULL);
2195 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2196 		crypto_ec_deinit(ecdh->ec);
2197 		wc_rng_deinit(ecdh->rng);
2198 		os_free(ecdh);
2199 	}
2200 }
2201 
2202 
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)2203 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
2204 {
2205 	struct wpabuf *buf = NULL;
2206 	int ret;
2207 	int len = ecdh->ec->key->dp->size;
2208 
2209 	buf = wpabuf_alloc(inc_y ? 2 * len : len);
2210 	if (!buf)
2211 		goto fail;
2212 
2213 	ret = crypto_bignum_to_bin((struct crypto_bignum *)
2214 				   ecdh->ec->key->pubkey.x, wpabuf_put(buf, len),
2215 				   len, len);
2216 	if (ret < 0)
2217 		goto fail;
2218 	if (inc_y) {
2219 		ret = crypto_bignum_to_bin((struct crypto_bignum *)
2220 					   ecdh->ec->key->pubkey.y,
2221 					   wpabuf_put(buf, len), len, len);
2222 		if (ret < 0)
2223 			goto fail;
2224 	}
2225 
2226 done:
2227 	return buf;
2228 fail:
2229 	wpabuf_free(buf);
2230 	buf = NULL;
2231 	goto done;
2232 }
2233 
2234 
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)2235 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
2236 					const u8 *key, size_t len)
2237 {
2238 	int ret;
2239 	struct wpabuf *pubkey = NULL;
2240 	struct wpabuf *secret = NULL;
2241 	word32 key_len = ecdh->ec->key->dp->size;
2242 	ecc_point *point = NULL;
2243 	size_t need_key_len = inc_y ? 2 * key_len : key_len;
2244 
2245 	if (len < need_key_len) {
2246 		LOG_WOLF_ERROR("key len too small");
2247 		goto fail;
2248 	}
2249 	pubkey = wpabuf_alloc(1 + 2 * key_len);
2250 	if (!pubkey) {
2251 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2252 		goto fail;
2253 	}
2254 	wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
2255 	wpabuf_put_data(pubkey, key, need_key_len);
2256 
2257 	point = wc_ecc_new_point();
2258 	if (!point) {
2259 		LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
2260 		goto fail;
2261 	}
2262 
2263 	ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
2264 				      ecdh->ec->key->idx, point);
2265 	if (ret != MP_OKAY) {
2266 		LOG_WOLF_ERROR_FUNC(wc_ecc_import_point_der, ret);
2267 		goto fail;
2268 	}
2269 
2270 	secret = wpabuf_alloc(key_len);
2271 	if (!secret) {
2272 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2273 		goto fail;
2274 	}
2275 
2276 	ret = wc_ecc_shared_secret_ex(ecdh->ec->key, point,
2277 				      wpabuf_put(secret, key_len), &key_len);
2278 	if (ret != MP_OKAY) {
2279 		LOG_WOLF_ERROR_FUNC(wc_ecc_shared_secret_ex, ret);
2280 		goto fail;
2281 	}
2282 
2283 done:
2284 	wc_ecc_del_point(point);
2285 	wpabuf_free(pubkey);
2286 	return secret;
2287 fail:
2288 	wpabuf_free(secret);
2289 	secret = NULL;
2290 	goto done;
2291 }
2292 
2293 
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)2294 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
2295 {
2296 	return crypto_ec_prime_len(ecdh->ec);
2297 }
2298 
crypto_ec_key_init(void)2299 static struct crypto_ec_key * crypto_ec_key_init(void)
2300 {
2301 	struct crypto_ec_key *key;
2302 
2303 	key = os_zalloc(sizeof(struct crypto_ec_key));
2304 	if (key) {
2305 		key->eckey = ecc_key_init();
2306 		/* Omit key->rng initialization because it seeds itself and thus
2307 		 * consumes entropy that may never be used. Lazy initialize when
2308 		 * necessary. */
2309 		if (!key->eckey) {
2310 			LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init);
2311 			crypto_ec_key_deinit(key);
2312 			key = NULL;
2313 		}
2314 	}
2315 	return key;
2316 }
2317 
2318 
crypto_ec_key_deinit(struct crypto_ec_key * key)2319 void crypto_ec_key_deinit(struct crypto_ec_key *key)
2320 {
2321 	if (key) {
2322 		ecc_key_deinit(key->eckey);
2323 		wc_rng_deinit(key->rng);
2324 		os_free(key);
2325 	}
2326 }
2327 
2328 
crypto_ec_key_init_rng(struct crypto_ec_key * key)2329 static WC_RNG * crypto_ec_key_init_rng(struct crypto_ec_key *key)
2330 {
2331 	if (!key->rng) {
2332 		/* Lazy init key->rng */
2333 		key->rng = wc_rng_init();
2334 		if (!key->rng)
2335 			LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
2336 	}
2337 	return key->rng;
2338 }
2339 
2340 
crypto_ec_key_parse_priv(const u8 * der,size_t der_len)2341 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
2342 {
2343 	struct crypto_ec_key *ret;
2344 	word32 idx = 0;
2345 	int err;
2346 
2347 	ret = crypto_ec_key_init();
2348 	if (!ret) {
2349 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2350 		goto fail;
2351 	}
2352 
2353 	err = wc_EccPrivateKeyDecode(der, &idx, ret->eckey, (word32) der_len);
2354 	if (err != 0) {
2355 		LOG_WOLF_ERROR_FUNC(wc_EccPrivateKeyDecode, err);
2356 		goto fail;
2357 	}
2358 
2359 	return ret;
2360 fail:
2361 	if (ret)
2362 		crypto_ec_key_deinit(ret);
2363 	return NULL;
2364 }
2365 
2366 
crypto_ec_key_group(struct crypto_ec_key * key)2367 int crypto_ec_key_group(struct crypto_ec_key *key)
2368 {
2369 
2370 	if (!key || !key->eckey || !key->eckey->dp) {
2371 		LOG_INVALID_PARAMETERS();
2372 		return -1;
2373 	}
2374 
2375 	switch (key->eckey->dp->id) {
2376 	case ECC_SECP256R1:
2377 		return 19;
2378 	case ECC_SECP384R1:
2379 		return 20;
2380 	case ECC_SECP521R1:
2381 		return 21;
2382 	case ECC_SECP192R1:
2383 		return 25;
2384 	case ECC_SECP224R1:
2385 		return 26;
2386 #ifdef HAVE_ECC_BRAINPOOL
2387 	case ECC_BRAINPOOLP224R1:
2388 		return 27;
2389 	case ECC_BRAINPOOLP256R1:
2390 		return 28;
2391 	case ECC_BRAINPOOLP384R1:
2392 		return 29;
2393 	case ECC_BRAINPOOLP512R1:
2394 		return 30;
2395 #endif /* HAVE_ECC_BRAINPOOL */
2396 	}
2397 
2398 	LOG_WOLF_ERROR_VA("Unsupported curve (id=%d) in EC key",
2399 			  key->eckey->dp->id);
2400 	return -1;
2401 }
2402 
2403 
crypto_ec_key_gen_public_key(struct crypto_ec_key * key)2404 static int crypto_ec_key_gen_public_key(struct crypto_ec_key *key)
2405 {
2406 	int err;
2407 
2408 #ifdef WOLFSSL_OLD_FIPS
2409 	err = wc_ecc_make_pub(key->eckey, NULL);
2410 #else /* WOLFSSL_OLD_FIPS */
2411 	/* Have wolfSSL generate the public key to make it available for output
2412 	 */
2413 	if (!crypto_ec_key_init_rng(key)) {
2414 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2415 		return -1;
2416 	}
2417 
2418 	err = wc_ecc_make_pub_ex(key->eckey, NULL, key->rng);
2419 #endif /* WOLFSSL_OLD_FIPS */
2420 
2421 	if (err != MP_OKAY) {
2422 		LOG_WOLF_ERROR_FUNC(wc_ecc_make_pub_ex, err);
2423 		return -1;
2424 	}
2425 
2426 	return 0;
2427 }
2428 
2429 
crypto_ec_key_get_subject_public_key(struct crypto_ec_key * key)2430 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
2431 {
2432 	int der_len;
2433 	struct wpabuf *ret = NULL;
2434 	int err;
2435 
2436 	if (!key || !key->eckey) {
2437 		LOG_INVALID_PARAMETERS();
2438 		goto fail;
2439 	}
2440 
2441 #ifdef WOLFSSL_OLD_FIPS
2442 	if (key->eckey->type == ECC_PRIVATEKEY_ONLY &&
2443 	    crypto_ec_key_gen_public_key(key) != 0) {
2444 		LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2445 		goto fail;
2446 	}
2447 #endif /* WOLFSSL_OLD_FIPS */
2448 
2449 	der_len = err = wc_EccPublicKeyToDer_ex(key->eckey, NULL, 0, 1, 1);
2450 	if (err == ECC_PRIVATEONLY_E) {
2451 		if (crypto_ec_key_gen_public_key(key) != 0) {
2452 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2453 			goto fail;
2454 		}
2455 		der_len = err = wc_EccPublicKeyToDer_ex(key->eckey, NULL, 0, 1,
2456 							1);
2457 	}
2458 	if (err <= 0) {
2459 		LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyDerSize, err);
2460 		goto fail;
2461 	}
2462 
2463 	ret = wpabuf_alloc(der_len);
2464 	if (!ret) {
2465 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2466 		goto fail;
2467 	}
2468 
2469 	err = wc_EccPublicKeyToDer_ex(key->eckey, wpabuf_mhead(ret), der_len, 1,
2470 				      1);
2471 	if (err == ECC_PRIVATEONLY_E) {
2472 		if (crypto_ec_key_gen_public_key(key) != 0) {
2473 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2474 			goto fail;
2475 		}
2476 		err = wc_EccPublicKeyToDer_ex(key->eckey, wpabuf_mhead(ret),
2477 					      der_len, 1, 1);
2478 	}
2479 	if (err <= 0) {
2480 		LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyToDer, err);
2481 		goto fail;
2482 	}
2483 	der_len = err;
2484 	wpabuf_put(ret, der_len);
2485 
2486 	return ret;
2487 
2488 fail:
2489 	wpabuf_free(ret);
2490 	return NULL;
2491 }
2492 
2493 
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)2494 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
2495 {
2496 	word32 idx = 0;
2497 	struct crypto_ec_key *ret = NULL;
2498 	int err;
2499 
2500 	ret = crypto_ec_key_init();
2501 	if (!ret) {
2502 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2503 		goto fail;
2504 	}
2505 
2506 	err = wc_EccPublicKeyDecode(der, &idx, ret->eckey, (word32) der_len);
2507 	if (err != 0) {
2508 		LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyDecode, err);
2509 		goto fail;
2510 	}
2511 
2512 	return ret;
2513 fail:
2514 	crypto_ec_key_deinit(ret);
2515 	return NULL;
2516 }
2517 
2518 
crypto_ec_key_sign(struct crypto_ec_key * key,const u8 * data,size_t len)2519 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
2520 				   size_t len)
2521 {
2522 	int der_len;
2523 	int err;
2524 	word32 w32_der_len;
2525 	struct wpabuf *ret = NULL;
2526 
2527 	if (!key || !key->eckey || !data || len == 0) {
2528 		LOG_INVALID_PARAMETERS();
2529 		goto fail;
2530 	}
2531 
2532 	if (!crypto_ec_key_init_rng(key)) {
2533 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2534 		goto fail;
2535 	}
2536 
2537 	der_len = wc_ecc_sig_size(key->eckey);
2538 	if (der_len <= 0) {
2539 		LOG_WOLF_ERROR_FUNC(wc_ecc_sig_size, der_len);
2540 		goto fail;
2541 	}
2542 
2543 	ret = wpabuf_alloc(der_len);
2544 	if (!ret) {
2545 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2546 		goto fail;
2547 	}
2548 
2549 	w32_der_len = (word32) der_len;
2550 	err = wc_ecc_sign_hash(data, len, wpabuf_mhead(ret), &w32_der_len,
2551 			       key->rng, key->eckey);
2552 	if (err != 0) {
2553 		LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash, err);
2554 		goto fail;
2555 	}
2556 	wpabuf_put(ret, w32_der_len);
2557 
2558 	return ret;
2559 fail:
2560 	wpabuf_free(ret);
2561 	return NULL;
2562 }
2563 
2564 
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)2565 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
2566 				   size_t len, const u8 *sig, size_t sig_len)
2567 {
2568 	int res = 0;
2569 
2570 	if (!key || !key->eckey || !data || len == 0 || !sig || sig_len == 0) {
2571 		LOG_INVALID_PARAMETERS();
2572 		return -1;
2573 	}
2574 
2575 	if (wc_ecc_verify_hash(sig, sig_len, data, len, &res, key->eckey) != 0)
2576 	{
2577 		LOG_WOLF_ERROR("wc_ecc_verify_hash failed");
2578 		return -1;
2579 	}
2580 
2581 	if (res != 1)
2582 		LOG_WOLF_ERROR("crypto_ec_key_verify_signature failed");
2583 
2584 	return res;
2585 }
2586 
2587 #endif /* CONFIG_ECC */
2588 
2589 #ifdef CONFIG_DPP
2590 
crypto_ec_key_get_ecprivate_key(struct crypto_ec_key * key,bool include_pub)2591 struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
2592 						bool include_pub)
2593 {
2594 	int len;
2595 	int err;
2596 	struct wpabuf *ret = NULL;
2597 
2598 	if (!key || !key->eckey) {
2599 		LOG_INVALID_PARAMETERS();
2600 		return NULL;
2601 	}
2602 
2603 #ifdef WOLFSSL_OLD_FIPS
2604 	if (key->eckey->type != ECC_PRIVATEKEY &&
2605 	    key->eckey->type != ECC_PRIVATEKEY_ONLY) {
2606 		LOG_INVALID_PARAMETERS();
2607 		return NULL;
2608 	}
2609 #endif /* WOLFSSL_OLD_FIPS */
2610 
2611 	len = err = wc_EccKeyDerSize(key->eckey, include_pub);
2612 	if (err == ECC_PRIVATEONLY_E && include_pub) {
2613 		if (crypto_ec_key_gen_public_key(key) != 0) {
2614 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2615 			return NULL;
2616 		}
2617 		len = err = wc_EccKeyDerSize(key->eckey, include_pub);
2618 	}
2619 	if (err <= 0) {
2620 		/* Exception for BAD_FUNC_ARG because higher levels blindly call
2621 		 * this function to determine if this is a private key or not.
2622 		 * BAD_FUNC_ARG most probably means that key->eckey is a public
2623 		 * key not private. */
2624 		if (err != BAD_FUNC_ARG)
2625 			LOG_WOLF_ERROR_FUNC(wc_EccKeyDerSize, err);
2626 		return NULL;
2627 	}
2628 
2629 	ret = wpabuf_alloc(len);
2630 	if (!ret) {
2631 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2632 		return NULL;
2633 	}
2634 
2635 	if (include_pub)
2636 		err = wc_EccKeyToDer(key->eckey, wpabuf_put(ret, len), len);
2637 	else
2638 		err = wc_EccPrivateKeyToDer(key->eckey, wpabuf_put(ret, len),
2639 					    len);
2640 
2641 	if (err != len) {
2642 		LOG_WOLF_ERROR_VA("%s failed with err: %d", include_pub ?
2643 				  "wc_EccKeyToDer" : "wc_EccPrivateKeyToDer",
2644 				  err);
2645 		wpabuf_free(ret);
2646 		ret = NULL;
2647 	}
2648 
2649 	return ret;
2650 }
2651 
2652 
crypto_ec_key_get_pubkey_point(struct crypto_ec_key * key,int prefix)2653 struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
2654 					       int prefix)
2655 {
2656 	int err;
2657 	word32 len = 0;
2658 	struct wpabuf *ret = NULL;
2659 
2660 	if (!key || !key->eckey) {
2661 		LOG_INVALID_PARAMETERS();
2662 		return NULL;
2663 	}
2664 
2665 	err = wc_ecc_export_x963(key->eckey, NULL, &len);
2666 	if (err != LENGTH_ONLY_E) {
2667 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2668 		goto fail;
2669 	}
2670 
2671 	ret = wpabuf_alloc(len);
2672 	if (!ret) {
2673 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2674 		goto fail;
2675 	}
2676 
2677 	err = wc_ecc_export_x963(key->eckey, wpabuf_mhead(ret), &len);
2678 	if (err == ECC_PRIVATEONLY_E) {
2679 		if (crypto_ec_key_gen_public_key(key) != 0) {
2680 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2681 			goto fail;
2682 		}
2683 		err = wc_ecc_export_x963(key->eckey, wpabuf_mhead(ret), &len);
2684 	}
2685 	if (err != MP_OKAY) {
2686 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2687 		goto fail;
2688 	}
2689 
2690 	if (!prefix)
2691 		os_memmove(wpabuf_mhead(ret), wpabuf_mhead_u8(ret) + 1,
2692 			   (size_t)--len);
2693 	wpabuf_put(ret, len);
2694 
2695 	return ret;
2696 
2697 fail:
2698 	wpabuf_free(ret);
2699 	return NULL;
2700 }
2701 
2702 
crypto_ec_key_set_pub(int group,const u8 * x,const u8 * y,size_t len)2703 struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
2704 					     const u8 *y, size_t len)
2705 {
2706 	struct crypto_ec_key *ret = NULL;
2707 	int curve_id = crypto_ec_group_2_id(group);
2708 	int err;
2709 
2710 	if (!x || !y || len == 0 || curve_id == ECC_CURVE_INVALID ||
2711 	    wc_ecc_get_curve_size_from_id(curve_id) != (int) len) {
2712 		LOG_INVALID_PARAMETERS();
2713 		return NULL;
2714 	}
2715 
2716 	ret = crypto_ec_key_init();
2717 	if (!ret) {
2718 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2719 		return NULL;
2720 	}
2721 
2722 	/* Cast necessary for FIPS API */
2723 	err = wc_ecc_import_unsigned(ret->eckey, (u8 *) x, (u8 *) y, NULL,
2724 				     curve_id);
2725 	if (err != MP_OKAY) {
2726 		LOG_WOLF_ERROR_FUNC(wc_ecc_import_unsigned, err);
2727 		crypto_ec_key_deinit(ret);
2728 		return NULL;
2729 	}
2730 
2731 	return ret;
2732 }
2733 
2734 
crypto_ec_key_cmp(struct crypto_ec_key * key1,struct crypto_ec_key * key2)2735 int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
2736 {
2737 	int ret;
2738 	struct wpabuf *key1_buf = crypto_ec_key_get_subject_public_key(key1);
2739 	struct wpabuf *key2_buf = crypto_ec_key_get_subject_public_key(key2);
2740 
2741 	if ((key1 && !key1_buf) || (key2 && !key2_buf)) {
2742 		LOG_WOLF_ERROR("crypto_ec_key_get_subject_public_key failed");
2743 		return -1;
2744 	}
2745 
2746 	ret = wpabuf_cmp(key1_buf, key2_buf);
2747 	if (ret != 0)
2748 		ret = -1; /* Default to -1 for different keys */
2749 
2750 	wpabuf_clear_free(key1_buf);
2751 	wpabuf_clear_free(key2_buf);
2752 	return ret;
2753 }
2754 
2755 
2756 /* wolfSSL doesn't have a pretty print function for keys so just print out the
2757  * PEM of the private key. */
crypto_ec_key_debug_print(const struct crypto_ec_key * key,const char * title)2758 void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
2759 			       const char *title)
2760 {
2761 	struct wpabuf * key_buf;
2762 	struct wpabuf * out = NULL;
2763 	int err;
2764 	int pem_len;
2765 
2766 	if (!key || !key->eckey) {
2767 		LOG_INVALID_PARAMETERS();
2768 		return;
2769 	}
2770 
2771 	if (key->eckey->type == ECC_PUBLICKEY)
2772 		key_buf = crypto_ec_key_get_subject_public_key(
2773 			(struct crypto_ec_key *) key);
2774 	else
2775 		key_buf = crypto_ec_key_get_ecprivate_key(
2776 			(struct crypto_ec_key *) key, 1);
2777 
2778 	if (!key_buf) {
2779 		LOG_WOLF_ERROR_VA("%s has returned NULL",
2780 				  key->eckey->type == ECC_PUBLICKEY ?
2781 				  "crypto_ec_key_get_subject_public_key" :
2782 				  "crypto_ec_key_get_ecprivate_key");
2783 		goto fail;
2784 	}
2785 
2786 	if (!title)
2787 		title = "";
2788 
2789 	err = wc_DerToPem(wpabuf_head(key_buf), wpabuf_len(key_buf), NULL, 0,
2790 			  ECC_TYPE);
2791 	if (err <= 0) {
2792 		LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
2793 		goto fail;
2794 	}
2795 	pem_len = err;
2796 
2797 	out = wpabuf_alloc(pem_len + 1);
2798 	if (!out) {
2799 		LOG_WOLF_ERROR_FUNC_NULL(wc_DerToPem);
2800 		goto fail;
2801 	}
2802 
2803 	err = wc_DerToPem(wpabuf_head(key_buf), wpabuf_len(key_buf),
2804 			  wpabuf_mhead(out), pem_len, ECC_TYPE);
2805 	if (err <= 0) {
2806 		LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
2807 		goto fail;
2808 	}
2809 
2810 	wpabuf_mhead_u8(out)[err] = '\0';
2811 	wpabuf_put(out, err + 1);
2812 	wpa_printf(MSG_DEBUG, "%s:\n%s", title,
2813 		   (const char *) wpabuf_head(out));
2814 
2815 fail:
2816 	wpabuf_clear_free(key_buf);
2817 	wpabuf_clear_free(out);
2818 }
2819 
2820 
crypto_ec_point_debug_print(const struct crypto_ec * e,const struct crypto_ec_point * p,const char * title)2821 void crypto_ec_point_debug_print(const struct crypto_ec *e,
2822 				 const struct crypto_ec_point *p,
2823 				 const char *title)
2824 {
2825 	u8 x[ECC_MAXSIZE];
2826 	u8 y[ECC_MAXSIZE];
2827 	int coord_size;
2828 	int err;
2829 
2830 	if (!p || !e) {
2831 		LOG_INVALID_PARAMETERS();
2832 		return;
2833 	}
2834 
2835 	coord_size = e->key->dp->size;
2836 
2837 	if (!title)
2838 		title = "";
2839 
2840 	err = crypto_ec_point_to_bin((struct crypto_ec *)e, p, x, y);
2841 	if (err != 0) {
2842 		LOG_WOLF_ERROR_FUNC(crypto_ec_point_to_bin, err);
2843 		return;
2844 	}
2845 
2846 	wpa_hexdump(MSG_DEBUG, title, x, coord_size);
2847 	wpa_hexdump(MSG_DEBUG, title, y, coord_size);
2848 }
2849 
2850 
crypto_ec_key_gen(int group)2851 struct crypto_ec_key * crypto_ec_key_gen(int group)
2852 {
2853 	int curve_id = crypto_ec_group_2_id(group);
2854 	int err;
2855 	struct crypto_ec_key * ret = NULL;
2856 
2857 	if (curve_id == ECC_CURVE_INVALID) {
2858 		LOG_INVALID_PARAMETERS();
2859 		return NULL;
2860 	}
2861 
2862 	ret = crypto_ec_key_init();
2863 	if (!ret) {
2864 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2865 		return NULL;
2866 	}
2867 
2868 	if (!crypto_ec_key_init_rng(ret)) {
2869 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2870 		goto fail;
2871 	}
2872 
2873 	err = wc_ecc_make_key_ex(ret->rng, 0, ret->eckey, curve_id);
2874 	if (err != MP_OKAY) {
2875 		LOG_WOLF_ERROR_FUNC(wc_ecc_make_key_ex, err);
2876 		goto fail;
2877 	}
2878 
2879 	return ret;
2880 fail:
2881 	crypto_ec_key_deinit(ret);
2882 	return NULL;
2883 }
2884 
2885 
crypto_ec_key_verify_signature_r_s(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * r,size_t r_len,const u8 * s,size_t s_len)2886 int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
2887 				       const u8 *data, size_t len,
2888 				       const u8 *r, size_t r_len,
2889 				       const u8 *s, size_t s_len)
2890 {
2891 	int err;
2892 	u8 sig[ECC_MAX_SIG_SIZE];
2893 	word32 sig_len = ECC_MAX_SIG_SIZE;
2894 
2895 	if (!key || !key->eckey || !data || !len || !r || !r_len ||
2896 	    !s || !s_len) {
2897 		LOG_INVALID_PARAMETERS();
2898 		return -1;
2899 	}
2900 
2901 	err = wc_ecc_rs_raw_to_sig(r, r_len, s, s_len, sig, &sig_len);
2902 	if (err != MP_OKAY) {
2903 		LOG_WOLF_ERROR_FUNC(wc_ecc_rs_raw_to_sig, err);
2904 		return -1;
2905 	}
2906 
2907 	return crypto_ec_key_verify_signature(key, data, len, sig, sig_len);
2908 }
2909 
2910 
crypto_ec_key_get_public_key(struct crypto_ec_key * key)2911 struct crypto_ec_point * crypto_ec_key_get_public_key(struct crypto_ec_key *key)
2912 {
2913 	ecc_point *point = NULL;
2914 	int err;
2915 	u8 *der = NULL;
2916 	word32 der_len = 0;
2917 
2918 	if (!key || !key->eckey || !key->eckey->dp) {
2919 		LOG_INVALID_PARAMETERS();
2920 		goto fail;
2921 	}
2922 
2923 	err = wc_ecc_export_x963(key->eckey, NULL, &der_len);
2924 	if (err != LENGTH_ONLY_E) {
2925 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2926 		goto fail;
2927 	}
2928 
2929 	der = os_malloc(der_len);
2930 	if (!der) {
2931 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
2932 		goto fail;
2933 	}
2934 
2935 	err = wc_ecc_export_x963(key->eckey, der, &der_len);
2936 	if (err == ECC_PRIVATEONLY_E) {
2937 		if (crypto_ec_key_gen_public_key(key) != 0) {
2938 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2939 			goto fail;
2940 		}
2941 		err = wc_ecc_export_x963(key->eckey, der, &der_len);
2942 	}
2943 	if (err != MP_OKAY) {
2944 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2945 		goto fail;
2946 	}
2947 
2948 	point = wc_ecc_new_point();
2949 	if (!point) {
2950 		LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
2951 		goto fail;
2952 	}
2953 
2954 	err = wc_ecc_import_point_der(der, der_len, key->eckey->idx, point);
2955 	if (err != MP_OKAY) {
2956 		LOG_WOLF_ERROR_FUNC(wc_ecc_import_point_der, err);
2957 		goto fail;
2958 	}
2959 
2960 	os_free(der);
2961 	return (struct crypto_ec_point *) point;
2962 
2963 fail:
2964 	os_free(der);
2965 	if (point)
2966 		wc_ecc_del_point(point);
2967 	return NULL;
2968 }
2969 
2970 
crypto_ec_key_get_private_key(struct crypto_ec_key * key)2971 struct crypto_bignum * crypto_ec_key_get_private_key(struct crypto_ec_key *key)
2972 {
2973 	u8 priv[ECC_MAXSIZE];
2974 	word32 priv_len = ECC_MAXSIZE;
2975 #ifdef WOLFSSL_OLD_FIPS
2976 	/* Needed to be compliant with the old API */
2977 	u8 qx[ECC_MAXSIZE];
2978 	word32 qx_len = ECC_MAXSIZE;
2979 	u8 qy[ECC_MAXSIZE];
2980 	word32 qy_len = ECC_MAXSIZE;
2981 #endif /* WOLFSSL_OLD_FIPS */
2982 	struct crypto_bignum *ret = NULL;
2983 	int err;
2984 
2985 	if (!key || !key->eckey) {
2986 		LOG_INVALID_PARAMETERS();
2987 		return NULL;
2988 	}
2989 
2990 #ifndef WOLFSSL_OLD_FIPS
2991 	err = wc_ecc_export_private_raw(key->eckey, NULL, NULL, NULL, NULL,
2992 					priv, &priv_len);
2993 #else /* WOLFSSL_OLD_FIPS */
2994 	err = wc_ecc_export_private_raw(key->eckey, qx, &qx_len, qy, &qy_len,
2995 					priv, &priv_len);
2996 #endif /* WOLFSSL_OLD_FIPS */
2997 	if (err != MP_OKAY) {
2998 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_private_raw, err);
2999 		return NULL;
3000 	}
3001 
3002 	ret = crypto_bignum_init_set(priv, priv_len);
3003 	forced_memzero(priv, priv_len);
3004 	return ret;
3005 }
3006 
3007 
crypto_ec_key_sign_r_s(struct crypto_ec_key * key,const u8 * data,size_t len)3008 struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
3009 				       const u8 *data, size_t len)
3010 {
3011 	int err;
3012 	u8 success = 0;
3013 	mp_int r;
3014 	mp_int s;
3015 	u8 rs_init = 0;
3016 	int sz;
3017 	struct wpabuf * ret = NULL;
3018 
3019 	if (!key || !key->eckey || !key->eckey->dp || !data || !len) {
3020 		LOG_INVALID_PARAMETERS();
3021 		return NULL;
3022 	}
3023 
3024 	sz = key->eckey->dp->size;
3025 
3026 	if (!crypto_ec_key_init_rng(key)) {
3027 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
3028 		goto fail;
3029 	}
3030 
3031 	err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL);
3032 	if (err != MP_OKAY) {
3033 		LOG_WOLF_ERROR_FUNC(mp_init_multi, err);
3034 		goto fail;
3035 	}
3036 	rs_init = 1;
3037 
3038 	err = wc_ecc_sign_hash_ex(data, len, key->rng, key->eckey, &r, &s);
3039 	if (err != MP_OKAY) {
3040 		LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash_ex, err);
3041 		goto fail;
3042 	}
3043 
3044 	if (mp_unsigned_bin_size(&r) > sz || mp_unsigned_bin_size(&s) > sz) {
3045 		LOG_WOLF_ERROR_VA("Unexpected size of r or s (%d %d %d)", sz,
3046 				  mp_unsigned_bin_size(&r),
3047 				  mp_unsigned_bin_size(&s));
3048 		goto fail;
3049 	}
3050 
3051 	ret = wpabuf_alloc(2 * sz);
3052 	if (!ret) {
3053 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3054 		goto fail;
3055 	}
3056 
3057 	err = mp_to_unsigned_bin_len(&r, wpabuf_put(ret, sz), sz);
3058 	if (err == MP_OKAY)
3059 		err = mp_to_unsigned_bin_len(&s, wpabuf_put(ret, sz), sz);
3060 	if (err != MP_OKAY) {
3061 		LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash_ex, err);
3062 		goto fail;
3063 	}
3064 
3065 	success = 1;
3066 fail:
3067 	if (rs_init) {
3068 		mp_free(&r);
3069 		mp_free(&s);
3070 	}
3071 	if (!success) {
3072 		wpabuf_free(ret);
3073 		ret = NULL;
3074 	}
3075 
3076 	return ret;
3077 }
3078 
3079 
3080 struct crypto_ec_key *
crypto_ec_key_set_pub_point(struct crypto_ec * e,const struct crypto_ec_point * pub)3081 crypto_ec_key_set_pub_point(struct crypto_ec *e,
3082 			    const struct crypto_ec_point *pub)
3083 {
3084 	struct crypto_ec_key  *ret = NULL;
3085 	int err;
3086 	byte *buf = NULL;
3087 	word32 buf_len = 0;
3088 
3089 	if (!e || !pub) {
3090 		LOG_INVALID_PARAMETERS();
3091 		return NULL;
3092 	}
3093 
3094 	/* Export to DER to not mess with wolfSSL internals */
3095 	err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(e->curve_id),
3096 				      (ecc_point *) pub, NULL, &buf_len);
3097 	if (err != LENGTH_ONLY_E || !buf_len) {
3098 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_point_der, err);
3099 		goto fail;
3100 	}
3101 
3102 	buf = os_malloc(buf_len);
3103 	if (!buf) {
3104 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3105 		goto fail;
3106 	}
3107 
3108 	err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(e->curve_id),
3109 			(ecc_point *) pub, buf, &buf_len);
3110 	if (err != MP_OKAY) {
3111 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_point_der, err);
3112 		goto fail;
3113 	}
3114 
3115 	ret = crypto_ec_key_init();
3116 	if (!ret) {
3117 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
3118 		goto fail;
3119 	}
3120 
3121 	err = wc_ecc_import_x963_ex(buf, buf_len, ret->eckey, e->curve_id);
3122 	if (err != MP_OKAY) {
3123 		LOG_WOLF_ERROR_FUNC(wc_ecc_import_x963_ex, err);
3124 		goto fail;
3125 	}
3126 
3127 	os_free(buf);
3128 	return ret;
3129 
3130 fail:
3131 	os_free(buf);
3132 	crypto_ec_key_deinit(ret);
3133 	return NULL;
3134 }
3135 
3136 
crypto_pkcs7_get_certificates(const struct wpabuf * pkcs7)3137 struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
3138 {
3139 	PKCS7 *p7 = NULL;
3140 	struct wpabuf *ret = NULL;
3141 	int err = 0;
3142 	int total_sz = 0;
3143 	int i;
3144 
3145 	if (!pkcs7) {
3146 		LOG_INVALID_PARAMETERS();
3147 		return NULL;
3148 	}
3149 
3150 	p7 = wc_PKCS7_New(NULL, INVALID_DEVID);
3151 	if (!p7) {
3152 		LOG_WOLF_ERROR_FUNC_NULL(wc_PKCS7_New);
3153 		return NULL;
3154 	}
3155 
3156 	err = wc_PKCS7_VerifySignedData(p7, (byte *) wpabuf_head(pkcs7),
3157 					wpabuf_len(pkcs7));
3158 	if (err != 0) {
3159 		LOG_WOLF_ERROR_FUNC(wc_PKCS7_VerifySignedData, err);
3160 		wc_PKCS7_Free(p7);
3161 		goto fail;
3162 	}
3163 
3164 	/* Need to access p7 members directly */
3165 	for (i = 0; i < MAX_PKCS7_CERTS; i++) {
3166 		if (p7->certSz[i] == 0)
3167 			continue;
3168 		err = wc_DerToPem(p7->cert[i], p7->certSz[i], NULL, 0,
3169 				  CERT_TYPE);
3170 		if (err > 0) {
3171 			total_sz += err;
3172 		} else {
3173 			LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
3174 			goto fail;
3175 		}
3176 	}
3177 
3178 	if (total_sz == 0) {
3179 		LOG_WOLF_ERROR("No certificates found in PKCS7 input");
3180 		goto fail;
3181 	}
3182 
3183 	ret = wpabuf_alloc(total_sz);
3184 	if (!ret) {
3185 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3186 		goto fail;
3187 	}
3188 
3189 	/* Need to access p7 members directly */
3190 	for (i = 0; i < MAX_PKCS7_CERTS; i++) {
3191 		if (p7->certSz[i] == 0)
3192 			continue;
3193 		/* Not using wpabuf_put() here so that wpabuf_overflow() isn't
3194 		 * called in case of a size mismatch. wc_DerToPem() checks if
3195 		 * the output is large enough internally. */
3196 		err = wc_DerToPem(p7->cert[i], p7->certSz[i],
3197 				  wpabuf_mhead_u8(ret) + wpabuf_len(ret),
3198 				  wpabuf_tailroom(ret),
3199 				  CERT_TYPE);
3200 		if (err > 0) {
3201 			wpabuf_put(ret, err);
3202 		} else {
3203 			LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
3204 			wpabuf_free(ret);
3205 			ret = NULL;
3206 			goto fail;
3207 		}
3208 	}
3209 
3210 fail:
3211 	if (p7)
3212 		wc_PKCS7_Free(p7);
3213 	return ret;
3214 }
3215 
3216 
3217 /* BEGIN Certificate Signing Request (CSR) APIs */
3218 
3219 enum cert_type {
3220 	cert_type_none = 0,
3221 	cert_type_decoded_cert,
3222 	cert_type_cert,
3223 };
3224 
3225 struct crypto_csr {
3226 	union {
3227 		/* For parsed csr should be read-only for higher levels */
3228 		DecodedCert dc;
3229 		Cert c; /* For generating a csr */
3230 	} req;
3231 	enum cert_type type;
3232 	struct crypto_ec_key *pubkey;
3233 };
3234 
3235 
3236 /* Helper function to make sure that the correct type is initialized */
crypto_csr_init_type(struct crypto_csr * csr,enum cert_type type,const byte * source,word32 in_sz)3237 static void crypto_csr_init_type(struct crypto_csr *csr, enum cert_type type,
3238 				 const byte *source, word32 in_sz)
3239 {
3240 	int err;
3241 
3242 	if (csr->type == type)
3243 		return; /* Already correct type */
3244 
3245 	switch (csr->type) {
3246 	case cert_type_decoded_cert:
3247 		wc_FreeDecodedCert(&csr->req.dc);
3248 		break;
3249 	case cert_type_cert:
3250 #ifdef WOLFSSL_CERT_GEN_CACHE
3251 		wc_SetCert_Free(&csr->req.c);
3252 #endif /* WOLFSSL_CERT_GEN_CACHE */
3253 		break;
3254 	case cert_type_none:
3255 		break;
3256 	}
3257 
3258 	switch (type) {
3259 	case cert_type_decoded_cert:
3260 		wc_InitDecodedCert(&csr->req.dc, source, in_sz, NULL);
3261 		break;
3262 	case cert_type_cert:
3263 		err = wc_InitCert(&csr->req.c);
3264 		if (err != 0)
3265 			LOG_WOLF_ERROR_FUNC(wc_InitCert, err);
3266 		break;
3267 	case cert_type_none:
3268 		break;
3269 	}
3270 
3271 	csr->type = type;
3272 }
3273 
3274 
crypto_csr_init(void)3275 struct crypto_csr * crypto_csr_init(void)
3276 {
3277 	struct crypto_csr *ret = os_malloc(sizeof(struct crypto_csr));
3278 
3279 	if (!ret) {
3280 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3281 		return NULL;
3282 	}
3283 
3284 	ret->type = cert_type_none;
3285 	crypto_csr_init_type(ret, cert_type_cert, NULL, 0);
3286 	ret->pubkey = NULL;
3287 
3288 	return ret;
3289 }
3290 
3291 
crypto_csr_deinit(struct crypto_csr * csr)3292 void crypto_csr_deinit(struct crypto_csr *csr)
3293 {
3294 	if (csr) {
3295 		crypto_csr_init_type(csr, cert_type_none, NULL, 0);
3296 		crypto_ec_key_deinit(csr->pubkey);
3297 		os_free(csr);
3298 	}
3299 }
3300 
3301 
crypto_csr_set_ec_public_key(struct crypto_csr * csr,struct crypto_ec_key * key)3302 int crypto_csr_set_ec_public_key(struct crypto_csr *csr,
3303 				 struct crypto_ec_key *key)
3304 {
3305 	struct wpabuf *der = NULL;
3306 
3307 	if (!csr || !key || !key->eckey) {
3308 		LOG_INVALID_PARAMETERS();
3309 		return -1;
3310 	}
3311 
3312 	if (csr->pubkey) {
3313 		crypto_ec_key_deinit(csr->pubkey);
3314 		csr->pubkey = NULL;
3315 	}
3316 
3317 	/* Create copy of key to mitigate use-after-free errors */
3318 	der = crypto_ec_key_get_subject_public_key(key);
3319 	if (!der) {
3320 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_get_subject_public_key);
3321 		return -1;
3322 	}
3323 
3324 	csr->pubkey = crypto_ec_key_parse_pub(wpabuf_head(der),
3325 					      wpabuf_len(der));
3326 	wpabuf_free(der);
3327 	if (!csr->pubkey) {
3328 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_parse_pub);
3329 		return -1;
3330 	}
3331 
3332 	return 0;
3333 }
3334 
3335 
crypto_csr_set_name(struct crypto_csr * csr,enum crypto_csr_name type,const char * name)3336 int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
3337 			const char *name)
3338 {
3339 	int name_len;
3340 	char *dest;
3341 
3342 	if (!csr || !name) {
3343 		LOG_INVALID_PARAMETERS();
3344 		return -1;
3345 	}
3346 
3347 	if (csr->type != cert_type_cert) {
3348 		LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3349 		return -1;
3350 	}
3351 
3352 	name_len = os_strlen(name);
3353 	if (name_len >= CTC_NAME_SIZE) {
3354 		LOG_WOLF_ERROR("name input too long");
3355 		return -1;
3356 	}
3357 
3358 	switch (type) {
3359 	case CSR_NAME_CN:
3360 		dest = csr->req.c.subject.commonName;
3361 		break;
3362 	case CSR_NAME_SN:
3363 		dest = csr->req.c.subject.sur;
3364 		break;
3365 	case CSR_NAME_C:
3366 		dest = csr->req.c.subject.country;
3367 		break;
3368 	case CSR_NAME_O:
3369 		dest = csr->req.c.subject.org;
3370 		break;
3371 	case CSR_NAME_OU:
3372 		dest = csr->req.c.subject.unit;
3373 		break;
3374 	default:
3375 		LOG_INVALID_PARAMETERS();
3376 		return -1;
3377 	}
3378 
3379 	os_memcpy(dest, name, name_len);
3380 	dest[name_len] = '\0';
3381 
3382 	return 0;
3383 }
3384 
3385 
crypto_csr_set_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,int attr_type,const u8 * value,size_t len)3386 int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
3387 			     int attr_type, const u8 *value, size_t len)
3388 {
3389 	if (!csr || attr_type != ASN1_TAG_UTF8STRING || !value ||
3390 	    len >= CTC_NAME_SIZE) {
3391 		LOG_INVALID_PARAMETERS();
3392 		return -1;
3393 	}
3394 
3395 	if (csr->type != cert_type_cert) {
3396 		LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3397 		return -1;
3398 	}
3399 
3400 	switch (attr) {
3401 	case CSR_ATTR_CHALLENGE_PASSWORD:
3402 		os_memcpy(csr->req.c.challengePw, value, len);
3403 		csr->req.c.challengePw[len] = '\0';
3404 		break;
3405 	default:
3406 		return -1;
3407 	}
3408 
3409 	return 0;
3410 }
3411 
3412 
crypto_csr_get_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,size_t * len,int * type)3413 const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
3414 				    enum crypto_csr_attr attr,
3415 				    size_t *len, int *type)
3416 {
3417 	if (!csr || !len || !type) {
3418 		LOG_INVALID_PARAMETERS();
3419 		return NULL;
3420 	}
3421 
3422 	switch (attr) {
3423 	case CSR_ATTR_CHALLENGE_PASSWORD:
3424 		switch (csr->type) {
3425 		case cert_type_decoded_cert:
3426 			*type = ASN1_TAG_UTF8STRING;
3427 			*len = csr->req.dc.cPwdLen;
3428 			return (const u8 *) csr->req.dc.cPwd;
3429 		case cert_type_cert:
3430 			*type = ASN1_TAG_UTF8STRING;
3431 			*len = os_strlen(csr->req.c.challengePw);
3432 			return (const u8 *) csr->req.c.challengePw;
3433 		case cert_type_none:
3434 			return NULL;
3435 		}
3436 		break;
3437 	}
3438 	return NULL;
3439 }
3440 
3441 
crypto_csr_sign(struct crypto_csr * csr,struct crypto_ec_key * key,enum crypto_hash_alg algo)3442 struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
3443 				struct crypto_ec_key *key,
3444 				enum crypto_hash_alg algo)
3445 {
3446 	int err;
3447 	int len;
3448 	u8 *buf = NULL;
3449 	int buf_len;
3450 	struct wpabuf *ret = NULL;
3451 
3452 	if (!csr || !key || !key->eckey) {
3453 		LOG_INVALID_PARAMETERS();
3454 		return NULL;
3455 	}
3456 
3457 	if (csr->type != cert_type_cert) {
3458 		LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3459 		return NULL;
3460 	}
3461 
3462 	if (!crypto_ec_key_init_rng(key)) {
3463 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
3464 		return NULL;
3465 	}
3466 
3467 	switch (algo) {
3468 	case CRYPTO_HASH_ALG_SHA256:
3469 		csr->req.c.sigType = CTC_SHA256wECDSA;
3470 		break;
3471 	case CRYPTO_HASH_ALG_SHA384:
3472 		csr->req.c.sigType = CTC_SHA384wECDSA;
3473 		break;
3474 	case CRYPTO_HASH_ALG_SHA512:
3475 		csr->req.c.sigType = CTC_SHA512wECDSA;
3476 		break;
3477 	default:
3478 		LOG_INVALID_PARAMETERS();
3479 		return NULL;
3480 	}
3481 
3482 	/* Pass in large value that is guaranteed to be larger than the
3483 	 * necessary buffer */
3484 	err = wc_MakeCertReq(&csr->req.c, NULL, 100000, NULL,
3485 			     csr->pubkey->eckey);
3486 	if (err <= 0) {
3487 		LOG_WOLF_ERROR_FUNC(wc_MakeCertReq, err);
3488 		goto fail;
3489 	}
3490 	len = err;
3491 
3492 	buf_len = len + MAX_SEQ_SZ * 2 + MAX_ENCODED_SIG_SZ;
3493 	buf = os_malloc(buf_len);
3494 	if (!buf) {
3495 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3496 		goto fail;
3497 	}
3498 
3499 	err = wc_MakeCertReq(&csr->req.c, buf, buf_len, NULL,
3500 			     csr->pubkey->eckey);
3501 	if (err <= 0) {
3502 		LOG_WOLF_ERROR_FUNC(wc_MakeCertReq, err);
3503 		goto fail;
3504 	}
3505 	len = err;
3506 
3507 	err = wc_SignCert(len, csr->req.c.sigType, buf, buf_len, NULL,
3508 			  key->eckey, key->rng);
3509 	if (err <= 0) {
3510 		LOG_WOLF_ERROR_FUNC(wc_SignCert, err);
3511 		goto fail;
3512 	}
3513 	len = err;
3514 
3515 	ret = wpabuf_alloc_copy(buf, len);
3516 	if (!ret) {
3517 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc_copy);
3518 		goto fail;
3519 	}
3520 
3521 fail:
3522 	os_free(buf);
3523 	return ret;
3524 }
3525 
3526 
crypto_csr_verify(const struct wpabuf * req)3527 struct crypto_csr * crypto_csr_verify(const struct wpabuf *req)
3528 {
3529 	struct crypto_csr *csr = NULL;
3530 	int err;
3531 
3532 	if (!req) {
3533 		LOG_INVALID_PARAMETERS();
3534 		return NULL;
3535 	}
3536 
3537 	csr = crypto_csr_init();
3538 	if (!csr) {
3539 		LOG_WOLF_ERROR_FUNC_NULL(crypto_csr_init);
3540 		goto fail;
3541 	}
3542 
3543 	crypto_csr_init_type(csr, cert_type_decoded_cert,
3544 			     wpabuf_head(req), wpabuf_len(req));
3545 	err = wc_ParseCert(&csr->req.dc, CERTREQ_TYPE, VERIFY, NULL);
3546 	if (err != 0) {
3547 		LOG_WOLF_ERROR_FUNC(wc_ParseCert, err);
3548 		goto fail;
3549 	}
3550 
3551 	return csr;
3552 fail:
3553 	crypto_csr_deinit(csr);
3554 	return NULL;
3555 }
3556 
3557 /* END Certificate Signing Request (CSR) APIs */
3558 
3559 #endif /* CONFIG_DPP */
3560 
3561 
3562 struct crypto_rsa_key {
3563 	RsaKey key;
3564 	WC_RNG *rng;
3565 };
3566 
crypto_rsa_key_init(void)3567 static struct crypto_rsa_key * crypto_rsa_key_init(void)
3568 {
3569 	struct crypto_rsa_key *ret;
3570 	int err;
3571 
3572 	ret = os_zalloc(sizeof(*ret));
3573 	if (!ret)
3574 		return NULL;
3575 
3576 	err = wc_InitRsaKey(&ret->key, NULL);
3577 	if (err != MP_OKAY) {
3578 		LOG_WOLF_ERROR_FUNC(wc_InitRsaKey, err);
3579 		goto fail;
3580 	}
3581 
3582 	ret->rng = wc_rng_init();
3583 	if (!ret->rng) {
3584 		LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
3585 		goto fail;
3586 	}
3587 
3588 	err = wc_RsaSetRNG(&ret->key, ret->rng);
3589 	if (err != 0) {
3590 		LOG_WOLF_ERROR_FUNC(wc_RsaSetRNG, err);
3591 		goto fail;
3592 	}
3593 
3594 	return ret;
3595 fail:
3596 	crypto_rsa_key_free(ret);
3597 	return NULL;
3598 }
3599 
3600 
crypto_rsa_key_free(struct crypto_rsa_key * key)3601 void crypto_rsa_key_free(struct crypto_rsa_key *key)
3602 {
3603 	if (key) {
3604 		int err;
3605 
3606 		err = wc_FreeRsaKey(&key->key);
3607 		if (err != 0)
3608 			LOG_WOLF_ERROR_FUNC(wc_FreeRsaKey, err);
3609 		wc_rng_free(key->rng);
3610 		os_free(key);
3611 	}
3612 }
3613 
3614 
read_rsa_key_from_x509(unsigned char * key_pem,size_t key_pem_len,DerBuffer ** key_der)3615 static void read_rsa_key_from_x509(unsigned char *key_pem, size_t key_pem_len,
3616 				   DerBuffer **key_der)
3617 {
3618 	struct DecodedCert cert;
3619 	DerBuffer *cert_der = NULL;
3620 	word32 der_key_sz = 0;
3621 	int err;
3622 
3623 	err = wc_PemToDer(key_pem, (long) key_pem_len, CERT_TYPE, &cert_der,
3624 			NULL, NULL, NULL);
3625 	if (err != 0) {
3626 		LOG_WOLF_ERROR_FUNC(wc_PemToDer, err);
3627 		goto fail;
3628 	}
3629 
3630 	wc_InitDecodedCert(&cert, cert_der->buffer, cert_der->length, NULL);
3631 	err = wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL);
3632 	if (err != 0) {
3633 		LOG_WOLF_ERROR_FUNC(wc_PemToDer, err);
3634 		goto fail;
3635 	}
3636 
3637 	err = wc_GetPubKeyDerFromCert(&cert, NULL, &der_key_sz);
3638 	if (err != LENGTH_ONLY_E) {
3639 		LOG_WOLF_ERROR_FUNC(wc_GetPubKeyDerFromCert, err);
3640 		goto fail;
3641 	}
3642 
3643 	if (*key_der)
3644 		wc_FreeDer(key_der);
3645 	*key_der = NULL;
3646 
3647 	err = wc_AllocDer(key_der, der_key_sz, PUBLICKEY_TYPE, NULL);
3648 	if (err != 0) {
3649 		LOG_WOLF_ERROR_FUNC(wc_AllocDer, err);
3650 		goto fail;
3651 	}
3652 
3653 	err = wc_GetPubKeyDerFromCert(&cert, (*key_der)->buffer,
3654 				      &(*key_der)->length);
3655 	if (err != 0) {
3656 		LOG_WOLF_ERROR_FUNC(wc_GetPubKeyDerFromCert, err);
3657 		goto fail;
3658 	}
3659 
3660 fail:
3661 	if (cert_der) {
3662 		wc_FreeDecodedCert(&cert);
3663 		wc_FreeDer(&cert_der);
3664 	}
3665 
3666 	/* caller is responsible for free'ing key_der */
3667 }
3668 
3669 
crypto_rsa_key_read(const char * file,bool private_key)3670 struct crypto_rsa_key * crypto_rsa_key_read(const char *file, bool private_key)
3671 {
3672 	struct crypto_rsa_key *ret = NULL;
3673 	unsigned char *key_pem = NULL;
3674 	size_t key_pem_len = 0;
3675 	DerBuffer *key_der = NULL;
3676 	int key_format = 0;
3677 	int err;
3678 	int success = 0;
3679 	word32 idx = 0;
3680 
3681 	key_pem = (unsigned char *) os_readfile(file, &key_pem_len);
3682 	if (!key_pem) {
3683 		LOG_WOLF_ERROR_FUNC_NULL(os_readfile);
3684 		goto fail;
3685 	}
3686 
3687 	err = wc_PemToDer(key_pem, (long) key_pem_len,
3688 			  private_key ? PRIVATEKEY_TYPE : PUBLICKEY_TYPE,
3689 			  &key_der, NULL, NULL, &key_format);
3690 	if (err != 0) {
3691 		if (private_key) {
3692 			LOG_WOLF_ERROR_FUNC(wc_PemToDer, err);
3693 			goto fail;
3694 		}
3695 
3696 		/* Input file might be public key or x509 cert we want to
3697 		 *extract the key from */
3698 		wpa_printf(MSG_DEBUG,
3699 			   "wolfSSL: Trying to extract key from x509 cert");
3700 		read_rsa_key_from_x509(key_pem, key_pem_len, &key_der);
3701 		if (!key_der) {
3702 			LOG_WOLF_ERROR_FUNC(wc_PemToDer, err);
3703 			LOG_WOLF_ERROR_FUNC_NULL(read_rsa_key_from_x509);
3704 			goto fail;
3705 		}
3706 	}
3707 
3708 	if (private_key && key_format != RSAk) {
3709 		LOG_WOLF_ERROR("Private key is not RSA key");
3710 		goto fail;
3711 	}
3712 
3713 	/* No longer needed so let's free the memory early */
3714 	os_free(key_pem);
3715 	key_pem = NULL;
3716 
3717 	ret = crypto_rsa_key_init();
3718 	if (!ret) {
3719 		LOG_WOLF_ERROR_FUNC_NULL(crypto_rsa_key_init);
3720 		goto fail;
3721 	}
3722 
3723 	if (private_key)
3724 		err = wc_RsaPrivateKeyDecode(key_der->buffer, &idx, &ret->key,
3725 					     key_der->length);
3726 	else
3727 		err = wc_RsaPublicKeyDecode(key_der->buffer, &idx, &ret->key,
3728 					    key_der->length);
3729 
3730 	if (err != 0) {
3731 		if (private_key)
3732 			LOG_WOLF_ERROR_FUNC(wc_RsaPrivateKeyDecode, err);
3733 		else
3734 			LOG_WOLF_ERROR_FUNC(wc_RsaPublicKeyDecode, err);
3735 		goto fail;
3736 	}
3737 
3738 	success = 1;
3739 fail:
3740 	os_free(key_pem);
3741 	if (key_der)
3742 		wc_FreeDer(&key_der);
3743 	if (!success && ret) {
3744 		crypto_rsa_key_free(ret);
3745 		ret = NULL;
3746 	}
3747 
3748 	return ret;
3749 }
3750 
3751 
crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key * key,const struct wpabuf * in)3752 struct wpabuf * crypto_rsa_oaep_sha256_encrypt(struct crypto_rsa_key *key,
3753 					       const struct wpabuf *in)
3754 {
3755 	int err;
3756 	int success = 0;
3757 	struct wpabuf *ret = NULL;
3758 
3759 	if (!key || !in) {
3760 		LOG_INVALID_PARAMETERS();
3761 		return NULL;
3762 	}
3763 
3764 	ret = wpabuf_alloc(wc_RsaEncryptSize(&key->key));
3765 	if (!ret) {
3766 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3767 		goto fail;
3768 	}
3769 
3770 	wpa_printf(MSG_DEBUG,
3771 		   "wolfSSL: crypto_rsa_oaep_sha256_encrypt: wpabuf_len(in) %ld  wc_RsaEncryptSize(key->key) %d",
3772 		   wpabuf_len(in), wc_RsaEncryptSize(&key->key));
3773 
3774 	err = wc_RsaPublicEncrypt_ex(wpabuf_head_u8(in), wpabuf_len(in),
3775 				     wpabuf_mhead_u8(ret), wpabuf_size(ret),
3776 				     &key->key, key->rng,
3777 				     WC_RSA_OAEP_PAD, WC_HASH_TYPE_SHA256,
3778 				     WC_MGF1SHA256, NULL, 0);
3779 	if (err <= 0) {
3780 		LOG_WOLF_ERROR_FUNC(wc_RsaPublicEncrypt_ex, err);
3781 		goto fail;
3782 	}
3783 	wpabuf_put(ret, err);
3784 
3785 	success = 1;
3786 fail:
3787 	if (!success && ret) {
3788 		wpabuf_free(ret);
3789 		ret = NULL;
3790 	}
3791 
3792 	return ret;
3793 }
3794 
3795 
crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key * key,const struct wpabuf * in)3796 struct wpabuf * crypto_rsa_oaep_sha256_decrypt(struct crypto_rsa_key *key,
3797 					       const struct wpabuf *in)
3798 {
3799 	int err;
3800 	int success = 0;
3801 	struct wpabuf *ret = NULL;
3802 
3803 	if (!key || !in) {
3804 		LOG_INVALID_PARAMETERS();
3805 		return NULL;
3806 	}
3807 
3808 	ret = wpabuf_alloc(wc_RsaEncryptSize(&key->key));
3809 	if (!ret) {
3810 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3811 		goto fail;
3812 	}
3813 
3814 	wpa_printf(MSG_DEBUG,
3815 		   "wolfSSL: crypto_rsa_oaep_sha256_decrypt: wpabuf_len(in) %ld wc_RsaEncryptSize(key->key) %d",
3816 		   wpabuf_len(in), wc_RsaEncryptSize(&key->key));
3817 
3818 	err = wc_RsaPrivateDecrypt_ex(wpabuf_head_u8(in), wpabuf_len(in),
3819 				      wpabuf_mhead_u8(ret), wpabuf_size(ret),
3820 				      &key->key, WC_RSA_OAEP_PAD,
3821 				      WC_HASH_TYPE_SHA256, WC_MGF1SHA256,
3822 				      NULL, 0);
3823 	if (err <= 0) {
3824 		LOG_WOLF_ERROR_FUNC(wc_RsaPublicEncrypt_ex, err);
3825 		goto fail;
3826 	}
3827 	wpabuf_put(ret, err);
3828 
3829 	success = 1;
3830 fail:
3831 	if (!success && ret) {
3832 		wpabuf_free(ret);
3833 		ret = NULL;
3834 	}
3835 
3836 	return ret;
3837 }
3838 
3839 
crypto_unload(void)3840 void crypto_unload(void)
3841 {
3842 }
3843