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