• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
wc_EccPublicKeyToDer_ex(ecc_key * key,byte * output,word32 inLen,int with_AlgCurve,int comp)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 
wc_rng_init(void)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 
wc_rng_deinit(WC_RNG * rng)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 
ecc_key_init(void)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 
ecc_key_deinit(ecc_key * key)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 
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
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)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 
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)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 
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)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 
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)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 
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)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 
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)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 
pbkdf2_sha1(const char * passphrase,const u8 * ssid,size_t ssid_len,int iterations,u8 * buf,size_t buflen)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
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)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 
aes_encrypt_init(const u8 * key,size_t len)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 
aes_encrypt(void * ctx,const u8 * plain,u8 * crypt)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 
aes_encrypt_deinit(void * ctx)597 void aes_encrypt_deinit(void *ctx)
598 {
599 	os_free(ctx);
600 }
601 
602 
aes_decrypt_init(const u8 * key,size_t len)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 
aes_decrypt(void * ctx,const u8 * crypt,u8 * plain)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 
aes_decrypt_deinit(void * ctx)646 void aes_decrypt_deinit(void *ctx)
647 {
648 	os_free(ctx);
649 }
650 
651 
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)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 
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)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
aes_wrap(const u8 * kek,size_t kek_len,int n,const u8 * plain,u8 * cipher)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 
aes_unwrap(const u8 * kek,size_t kek_len,int n,const u8 * cipher,u8 * plain)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
rc4_skip(const u8 * key,size_t keylen,size_t skip,u8 * data,size_t data_len)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 
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)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 
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)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 
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)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 
crypto_cipher_deinit(struct crypto_cipher * ctx)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 
dh5_init(struct wpabuf ** priv,struct wpabuf ** publ)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 
dh5_init_fixed(const struct wpabuf * priv,const struct wpabuf * publ)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 
dh5_derive_shared(void * ctx,const struct wpabuf * peer_public,const struct wpabuf * own_private)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 
dh5_free(void * ctx)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 
crypto_dh_init(u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)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 
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)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
crypto_get_random(void * buf,size_t len)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 
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)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 
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)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 
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)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 
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)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 
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)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 
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)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 
crypto_bignum_init(void)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 
crypto_bignum_init_set(const u8 * buf,size_t len)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 
crypto_bignum_init_uint(unsigned int val)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 
crypto_bignum_deinit(struct crypto_bignum * n,int clear)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 
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)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 
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)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 
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)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 
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)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 
crypto_bignum_exptmod(const struct crypto_bignum * b,const struct crypto_bignum * e,const struct crypto_bignum * m,struct crypto_bignum * r)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 
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)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 
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)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 
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * d)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 
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)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 
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * m,struct crypto_bignum * d)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 
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)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 
crypto_bignum_sqrtmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1528 int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
1529 			  const struct crypto_bignum *b,
1530 			  struct crypto_bignum *c)
1531 {
1532 	/* TODO */
1533 	return -1;
1534 }
1535 
1536 
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)1537 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1538 			 struct crypto_bignum *r)
1539 {
1540 	if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1541 		return -1;
1542 	mp_rshb((mp_int *) r, n);
1543 	return 0;
1544 }
1545 
1546 
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)1547 int crypto_bignum_cmp(const struct crypto_bignum *a,
1548 		      const struct crypto_bignum *b)
1549 {
1550 	return mp_cmp((mp_int *) a, (mp_int *) b);
1551 }
1552 
1553 
crypto_bignum_is_zero(const struct crypto_bignum * a)1554 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1555 {
1556 	return mp_iszero((mp_int *) a);
1557 }
1558 
1559 
crypto_bignum_is_one(const struct crypto_bignum * a)1560 int crypto_bignum_is_one(const struct crypto_bignum *a)
1561 {
1562 	return mp_isone((const mp_int *) a);
1563 }
1564 
crypto_bignum_is_odd(const struct crypto_bignum * a)1565 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1566 {
1567 	return mp_isodd((mp_int *) a);
1568 }
1569 
1570 
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)1571 int crypto_bignum_legendre(const struct crypto_bignum *a,
1572 			   const struct crypto_bignum *p)
1573 {
1574 	mp_int t;
1575 	int ret;
1576 	int res = -2;
1577 
1578 	if (TEST_FAIL())
1579 		return -2;
1580 
1581 	if (mp_init(&t) != MP_OKAY)
1582 		return -2;
1583 
1584 	/* t = (p-1) / 2 */
1585 	ret = mp_sub_d((mp_int *) p, 1, &t);
1586 	if (ret == MP_OKAY)
1587 		mp_rshb(&t, 1);
1588 	if (ret == MP_OKAY)
1589 		ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1590 	if (ret == MP_OKAY) {
1591 		if (mp_isone(&t))
1592 			res = 1;
1593 		else if (mp_iszero(&t))
1594 			res = 0;
1595 		else
1596 			res = -1;
1597 	}
1598 
1599 	mp_clear(&t);
1600 	return res;
1601 }
1602 
1603 
1604 #ifdef CONFIG_ECC
1605 
crypto_ec_group_2_id(int group)1606 static int crypto_ec_group_2_id(int group)
1607 {
1608 	switch (group) {
1609 	case 19:
1610 		return ECC_SECP256R1;
1611 	case 20:
1612 		return ECC_SECP384R1;
1613 	case 21:
1614 		return ECC_SECP521R1;
1615 	case 25:
1616 		return ECC_SECP192R1;
1617 	case 26:
1618 		return ECC_SECP224R1;
1619 #ifdef HAVE_ECC_BRAINPOOL
1620 	case 27:
1621 		return ECC_BRAINPOOLP224R1;
1622 	case 28:
1623 		return ECC_BRAINPOOLP256R1;
1624 	case 29:
1625 		return ECC_BRAINPOOLP384R1;
1626 	case 30:
1627 		return ECC_BRAINPOOLP512R1;
1628 #endif /* HAVE_ECC_BRAINPOOL */
1629 	default:
1630 		LOG_WOLF_ERROR_VA("Unsupported curve (id=%d) in EC key", group);
1631 		return ECC_CURVE_INVALID;
1632 	}
1633 }
1634 
1635 
1636 int ecc_map(ecc_point *, mp_int *, mp_digit);
1637 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1638 			     mp_int *a, mp_int *modulus, mp_digit mp);
1639 
1640 struct crypto_ec {
1641 	ecc_key *key;
1642 #ifdef CONFIG_DPP
1643 	ecc_point *g; /* Only used in DPP for now */
1644 #endif /* CONFIG_DPP */
1645 	mp_int a;
1646 	mp_int prime;
1647 	mp_int order;
1648 	mp_digit mont_b;
1649 	mp_int b;
1650 	int curve_id;
1651 	bool own_key; /* Should we free the `key` */
1652 };
1653 
1654 
crypto_ec_init(int group)1655 struct crypto_ec * crypto_ec_init(int group)
1656 {
1657 	int built = 0;
1658 	struct crypto_ec *e;
1659 	int curve_id = crypto_ec_group_2_id(group);
1660 	int err;
1661 
1662 	if (curve_id == ECC_CURVE_INVALID) {
1663 		LOG_INVALID_PARAMETERS();
1664 		return NULL;
1665 	}
1666 
1667 	e = os_zalloc(sizeof(*e));
1668 	if (!e) {
1669 		LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
1670 		return NULL;
1671 	}
1672 
1673 	e->curve_id = curve_id;
1674 	e->own_key = true;
1675 	e->key = ecc_key_init();
1676 	if (!e->key) {
1677 		LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init);
1678 		goto done;
1679 	}
1680 
1681 	err = wc_ecc_set_curve(e->key, 0, curve_id);
1682 	if (err != 0) {
1683 		LOG_WOLF_ERROR_FUNC(wc_ecc_set_curve, err);
1684 		goto done;
1685 	}
1686 #ifdef CONFIG_DPP
1687 	e->g = wc_ecc_new_point();
1688 	if (!e->g) {
1689 		LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
1690 		goto done;
1691 	}
1692 #ifdef CONFIG_FIPS
1693 	/* Setup generator manually in FIPS mode */
1694 	if (!e->key->dp) {
1695 		LOG_WOLF_ERROR_FUNC_NULL(e->key->dp);
1696 		goto done;
1697 	}
1698 	err = mp_read_radix(e->g->x, e->key->dp->Gx, MP_RADIX_HEX);
1699 	if (err != MP_OKAY) {
1700 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1701 		goto done;
1702 	}
1703 	err = mp_read_radix(e->g->y, e->key->dp->Gy, MP_RADIX_HEX);
1704 	if (err != MP_OKAY) {
1705 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1706 		goto done;
1707 	}
1708 	err = mp_set(e->g->z, 1);
1709 	if (err != MP_OKAY) {
1710 		LOG_WOLF_ERROR_FUNC(mp_set, err);
1711 		goto done;
1712 	}
1713 #else /* CONFIG_FIPS */
1714 	err = wc_ecc_get_generator(e->g, wc_ecc_get_curve_idx(curve_id));
1715 	if (err != MP_OKAY) {
1716 		LOG_WOLF_ERROR_FUNC(wc_ecc_get_generator, err);
1717 		goto done;
1718 	}
1719 #endif /* CONFIG_FIPS */
1720 #endif /* CONFIG_DPP */
1721 	err = mp_init_multi(&e->a, &e->prime, &e->order, &e->b, NULL, NULL);
1722 	if (err != MP_OKAY) {
1723 		LOG_WOLF_ERROR_FUNC(mp_init_multi, err);
1724 		goto done;
1725 	}
1726 	err = mp_read_radix(&e->a, e->key->dp->Af, 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->b, e->key->dp->Bf, 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->prime, e->key->dp->prime, 16);
1737 	if (err != MP_OKAY) {
1738 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1739 		goto done;
1740 	}
1741 	err = mp_read_radix(&e->order, e->key->dp->order, 16);
1742 	if (err != MP_OKAY) {
1743 		LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1744 		goto done;
1745 	}
1746 	err = mp_montgomery_setup(&e->prime, &e->mont_b);
1747 	if (err != MP_OKAY) {
1748 		LOG_WOLF_ERROR_FUNC(mp_montgomery_setup, err);
1749 		goto done;
1750 	}
1751 
1752 	built = 1;
1753 done:
1754 	if (!built) {
1755 		crypto_ec_deinit(e);
1756 		e = NULL;
1757 	}
1758 	return e;
1759 }
1760 
1761 
crypto_ec_deinit(struct crypto_ec * e)1762 void crypto_ec_deinit(struct crypto_ec* e)
1763 {
1764 	if (!e)
1765 		return;
1766 
1767 	mp_clear(&e->b);
1768 	mp_clear(&e->order);
1769 	mp_clear(&e->prime);
1770 	mp_clear(&e->a);
1771 #ifdef CONFIG_DPP
1772 	wc_ecc_del_point(e->g);
1773 #endif /* CONFIG_DPP */
1774 	if (e->own_key)
1775 		ecc_key_deinit(e->key);
1776 	os_free(e);
1777 }
1778 
1779 
crypto_ec_point_init(struct crypto_ec * e)1780 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1781 {
1782 	if (TEST_FAIL())
1783 		return NULL;
1784 	if (!e)
1785 		return NULL;
1786 	return (struct crypto_ec_point *) wc_ecc_new_point();
1787 }
1788 
1789 
crypto_ec_prime_len(struct crypto_ec * e)1790 size_t crypto_ec_prime_len(struct crypto_ec *e)
1791 {
1792 	return (mp_count_bits(&e->prime) + 7) / 8;
1793 }
1794 
1795 
crypto_ec_prime_len_bits(struct crypto_ec * e)1796 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1797 {
1798 	return mp_count_bits(&e->prime);
1799 }
1800 
1801 
crypto_ec_order_len(struct crypto_ec * e)1802 size_t crypto_ec_order_len(struct crypto_ec *e)
1803 {
1804 	return (mp_count_bits(&e->order) + 7) / 8;
1805 }
1806 
1807 
crypto_ec_get_prime(struct crypto_ec * e)1808 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1809 {
1810 	return (const struct crypto_bignum *) &e->prime;
1811 }
1812 
1813 
crypto_ec_get_order(struct crypto_ec * e)1814 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1815 {
1816 	return (const struct crypto_bignum *) &e->order;
1817 }
1818 
1819 
crypto_ec_get_a(struct crypto_ec * e)1820 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1821 {
1822 	return (const struct crypto_bignum *) &e->a;
1823 }
1824 
1825 
crypto_ec_get_b(struct crypto_ec * e)1826 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1827 {
1828 	return (const struct crypto_bignum *) &e->b;
1829 }
1830 
1831 
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)1832 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1833 {
1834 	ecc_point *point = (ecc_point *) p;
1835 
1836 	if (!p)
1837 		return;
1838 
1839 	if (clear) {
1840 #ifdef CONFIG_FIPS
1841 		mp_forcezero(point->x);
1842 		mp_forcezero(point->y);
1843 		mp_forcezero(point->z);
1844 #else /* CONFIG_FIPS */
1845 		wc_ecc_forcezero_point(point);
1846 #endif /* CONFIG_FIPS */
1847 	}
1848 	wc_ecc_del_point(point);
1849 }
1850 
1851 
1852 #ifdef CONFIG_DPP
crypto_ec_get_generator(struct crypto_ec * e)1853 const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
1854 {
1855 	return (const struct crypto_ec_point *) e->g;
1856 }
1857 #endif /* CONFIG_DPP */
1858 
1859 
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)1860 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1861 		      struct crypto_bignum *x)
1862 {
1863 	return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1864 }
1865 
1866 
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)1867 int crypto_ec_point_to_bin(struct crypto_ec *e,
1868 			   const struct crypto_ec_point *point, u8 *x, u8 *y)
1869 {
1870 	ecc_point *p = (ecc_point *) point;
1871 	int len;
1872 	int err;
1873 
1874 	if (TEST_FAIL())
1875 		return -1;
1876 
1877 	if (!mp_isone(p->z)) {
1878 		err = ecc_map(p, &e->prime, e->mont_b);
1879 		if (err != MP_OKAY) {
1880 			LOG_WOLF_ERROR_FUNC(ecc_map, err);
1881 			return -1;
1882 		}
1883 	}
1884 
1885 	len = wc_ecc_get_curve_size_from_id(e->curve_id);
1886 	if (len <= 0) {
1887 		LOG_WOLF_ERROR_FUNC(wc_ecc_get_curve_size_from_id, len);
1888 		LOG_WOLF_ERROR_VA("wc_ecc_get_curve_size_from_id error for curve_id %d", e->curve_id);
1889 		return -1;
1890 	}
1891 
1892 	if (x) {
1893 		if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1894 					 (size_t) len, (size_t) len) <= 0) {
1895 			LOG_WOLF_ERROR_FUNC(crypto_bignum_to_bin, -1);
1896 			return -1;
1897 		}
1898 	}
1899 
1900 	if (y) {
1901 		if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1902 					 (size_t) len, (size_t) len) <= 0) {
1903 			LOG_WOLF_ERROR_FUNC(crypto_bignum_to_bin, -1);
1904 			return -1;
1905 		}
1906 	}
1907 
1908 	return 0;
1909 }
1910 
1911 
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)1912 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1913 						  const u8 *val)
1914 {
1915 	ecc_point *point = NULL;
1916 	int loaded = 0;
1917 
1918 	if (TEST_FAIL())
1919 		return NULL;
1920 
1921 	point = wc_ecc_new_point();
1922 	if (!point)
1923 		goto done;
1924 
1925 	if (mp_read_unsigned_bin(point->x, val, e->key->dp->size) != MP_OKAY)
1926 		goto done;
1927 	val += e->key->dp->size;
1928 	if (mp_read_unsigned_bin(point->y, val, e->key->dp->size) != MP_OKAY)
1929 		goto done;
1930 	mp_set(point->z, 1);
1931 
1932 	loaded = 1;
1933 done:
1934 	if (!loaded) {
1935 		wc_ecc_del_point(point);
1936 		point = NULL;
1937 	}
1938 	return (struct crypto_ec_point *) point;
1939 }
1940 
1941 
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)1942 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1943 			const struct crypto_ec_point *b,
1944 			struct crypto_ec_point *c)
1945 {
1946 	mp_int mu;
1947 	ecc_point *ta = NULL, *tb = NULL;
1948 	ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1949 	mp_int *modulus = &e->prime;
1950 	int ret;
1951 
1952 	if (TEST_FAIL())
1953 		return -1;
1954 
1955 	ret = mp_init(&mu);
1956 	if (ret != MP_OKAY)
1957 		return -1;
1958 
1959 	ret = mp_montgomery_calc_normalization(&mu, modulus);
1960 	if (ret != MP_OKAY) {
1961 		mp_clear(&mu);
1962 		return -1;
1963 	}
1964 
1965 	if (!mp_isone(&mu)) {
1966 		ta = wc_ecc_new_point();
1967 		if (!ta) {
1968 			mp_clear(&mu);
1969 			return -1;
1970 		}
1971 		tb = wc_ecc_new_point();
1972 		if (!tb) {
1973 			wc_ecc_del_point(ta);
1974 			mp_clear(&mu);
1975 			return -1;
1976 		}
1977 
1978 		if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1979 		    mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1980 		    mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1981 		    mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1982 		    mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1983 		    mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1984 			ret = -1;
1985 			goto end;
1986 		}
1987 		pa = ta;
1988 		pb = tb;
1989 	}
1990 
1991 	ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1992 				       &e->prime, e->mont_b);
1993 	if (ret != 0) {
1994 		ret = -1;
1995 		goto end;
1996 	}
1997 
1998 	if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1999 		ret = -1;
2000 	else
2001 		ret = 0;
2002 end:
2003 	wc_ecc_del_point(tb);
2004 	wc_ecc_del_point(ta);
2005 	mp_clear(&mu);
2006 	return ret;
2007 }
2008 
2009 
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)2010 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
2011 			const struct crypto_bignum *b,
2012 			struct crypto_ec_point *res)
2013 {
2014 	int ret;
2015 
2016 	if (TEST_FAIL())
2017 		return -1;
2018 
2019 	ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
2020 			    &e->a, &e->prime, 1);
2021 	return ret == 0 ? 0 : -1;
2022 }
2023 
2024 
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)2025 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
2026 {
2027 	ecc_point *point = (ecc_point *) p;
2028 
2029 	if (TEST_FAIL())
2030 		return -1;
2031 
2032 	if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
2033 		return -1;
2034 
2035 	return 0;
2036 }
2037 
2038 
2039 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)2040 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
2041 			      const struct crypto_bignum *x)
2042 {
2043 	mp_int *y2;
2044 
2045 	if (TEST_FAIL())
2046 		return NULL;
2047 
2048 	/* y^2 = x^3 + ax + b = (x^2 + a)x + b */
2049 	y2 = (mp_int *) crypto_bignum_init();
2050 	if (!y2 ||
2051 	    mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
2052 	    mp_addmod(y2, &e->a, &e->prime, y2) != 0 ||
2053 	    mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
2054 	    mp_addmod(y2, &e->b, &e->prime, y2) != 0) {
2055 		mp_clear(y2);
2056 		os_free(y2);
2057 		y2 = NULL;
2058 	}
2059 
2060 	return (struct crypto_bignum *) y2;
2061 }
2062 
2063 
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)2064 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
2065 				   const struct crypto_ec_point *p)
2066 {
2067 	return wc_ecc_point_is_at_infinity((ecc_point *) p);
2068 }
2069 
2070 
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)2071 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
2072 				const struct crypto_ec_point *p)
2073 {
2074 	return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
2075 		MP_OKAY;
2076 }
2077 
2078 
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)2079 int crypto_ec_point_cmp(const struct crypto_ec *e,
2080 			const struct crypto_ec_point *a,
2081 			const struct crypto_ec_point *b)
2082 {
2083 	return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
2084 }
2085 
2086 struct crypto_ec_key {
2087 	ecc_key *eckey;
2088 	WC_RNG *rng; /* Needs to be initialized before use.
2089 		      * *NOT* initialized in crypto_ec_key_init */
2090 };
2091 
2092 
2093 struct crypto_ecdh {
2094 	struct crypto_ec *ec;
2095 	WC_RNG *rng;
2096 };
2097 
_crypto_ecdh_init(int group)2098 static struct crypto_ecdh * _crypto_ecdh_init(int group)
2099 {
2100 	struct crypto_ecdh *ecdh = NULL;
2101 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2102 	int ret;
2103 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2104 
2105 	ecdh = os_zalloc(sizeof(*ecdh));
2106 	if (!ecdh) {
2107 		LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
2108 		return NULL;
2109 	}
2110 
2111 	ecdh->rng = wc_rng_init();
2112 	if (!ecdh->rng) {
2113 		LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
2114 		goto fail;
2115 	}
2116 
2117 	ecdh->ec = crypto_ec_init(group);
2118 	if (!ecdh->ec) {
2119 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_init);
2120 		goto fail;
2121 	}
2122 
2123 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2124 	ret = wc_ecc_set_rng(ecdh->ec->key, ecdh->rng);
2125 	if (ret != 0) {
2126 		LOG_WOLF_ERROR_FUNC(wc_ecc_set_rng, ret);
2127 		goto fail;
2128 	}
2129 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2130 
2131 	return ecdh;
2132 fail:
2133 	crypto_ecdh_deinit(ecdh);
2134 	return NULL;
2135 }
2136 
2137 
crypto_ecdh_init(int group)2138 struct crypto_ecdh * crypto_ecdh_init(int group)
2139 {
2140 	struct crypto_ecdh *ret = NULL;
2141 	int err;
2142 
2143 	ret = _crypto_ecdh_init(group);
2144 
2145 	if (!ret) {
2146 		LOG_WOLF_ERROR_FUNC_NULL(_crypto_ecdh_init);
2147 		return NULL;
2148 	}
2149 
2150 	err = wc_ecc_make_key_ex(ret->rng, 0, ret->ec->key,
2151 				 crypto_ec_group_2_id(group));
2152 	if (err != MP_OKAY) {
2153 		LOG_WOLF_ERROR_FUNC(wc_ecc_make_key_ex, err);
2154 		crypto_ecdh_deinit(ret);
2155 		ret = NULL;
2156 	}
2157 
2158 	return ret;
2159 }
2160 
2161 
crypto_ecdh_init2(int group,struct crypto_ec_key * own_key)2162 struct crypto_ecdh * crypto_ecdh_init2(int group, struct crypto_ec_key *own_key)
2163 {
2164 	struct crypto_ecdh *ret = NULL;
2165 
2166 	if (!own_key || crypto_ec_key_group(own_key) != group) {
2167 		LOG_INVALID_PARAMETERS();
2168 		return NULL;
2169 	}
2170 
2171 	ret = _crypto_ecdh_init(group);
2172 	if (ret) {
2173 		/* Already init'ed to the right group. Enough to substitute the
2174 		 * key. */
2175 		ecc_key_deinit(ret->ec->key);
2176 		ret->ec->key = own_key->eckey;
2177 		ret->ec->own_key = false;
2178 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2179 		if (!ret->ec->key->rng) {
2180 			int err = wc_ecc_set_rng(ret->ec->key, ret->rng);
2181 
2182 			if (err != 0)
2183 				LOG_WOLF_ERROR_FUNC(wc_ecc_set_rng, err);
2184 		}
2185 #endif /* ECC_TIMING_RESISTANT && !CONFIG_FIPS */
2186 	}
2187 
2188 	return ret;
2189 }
2190 
2191 
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)2192 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
2193 {
2194 	if (ecdh) {
2195 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2196 		/* Disassociate the rng */
2197 		if (ecdh->ec && ecdh->ec->key &&
2198 		    ecdh->ec->key->rng == ecdh->rng)
2199 			(void) wc_ecc_set_rng(ecdh->ec->key, NULL);
2200 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2201 		crypto_ec_deinit(ecdh->ec);
2202 		wc_rng_deinit(ecdh->rng);
2203 		os_free(ecdh);
2204 	}
2205 }
2206 
2207 
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)2208 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
2209 {
2210 	struct wpabuf *buf = NULL;
2211 	int ret;
2212 	int len = ecdh->ec->key->dp->size;
2213 
2214 	buf = wpabuf_alloc(inc_y ? 2 * len : len);
2215 	if (!buf)
2216 		goto fail;
2217 
2218 	ret = crypto_bignum_to_bin((struct crypto_bignum *)
2219 				   ecdh->ec->key->pubkey.x, wpabuf_put(buf, len),
2220 				   len, len);
2221 	if (ret < 0)
2222 		goto fail;
2223 	if (inc_y) {
2224 		ret = crypto_bignum_to_bin((struct crypto_bignum *)
2225 					   ecdh->ec->key->pubkey.y,
2226 					   wpabuf_put(buf, len), len, len);
2227 		if (ret < 0)
2228 			goto fail;
2229 	}
2230 
2231 done:
2232 	return buf;
2233 fail:
2234 	wpabuf_free(buf);
2235 	buf = NULL;
2236 	goto done;
2237 }
2238 
2239 
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)2240 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
2241 					const u8 *key, size_t len)
2242 {
2243 	int ret;
2244 	struct wpabuf *pubkey = NULL;
2245 	struct wpabuf *secret = NULL;
2246 	word32 key_len = ecdh->ec->key->dp->size;
2247 	ecc_point *point = NULL;
2248 	size_t need_key_len = inc_y ? 2 * key_len : key_len;
2249 
2250 	if (len < need_key_len) {
2251 		LOG_WOLF_ERROR("key len too small");
2252 		goto fail;
2253 	}
2254 	pubkey = wpabuf_alloc(1 + 2 * key_len);
2255 	if (!pubkey) {
2256 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2257 		goto fail;
2258 	}
2259 	wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
2260 	wpabuf_put_data(pubkey, key, need_key_len);
2261 
2262 	point = wc_ecc_new_point();
2263 	if (!point) {
2264 		LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
2265 		goto fail;
2266 	}
2267 
2268 	ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
2269 				      ecdh->ec->key->idx, point);
2270 	if (ret != MP_OKAY) {
2271 		LOG_WOLF_ERROR_FUNC(wc_ecc_import_point_der, ret);
2272 		goto fail;
2273 	}
2274 
2275 	secret = wpabuf_alloc(key_len);
2276 	if (!secret) {
2277 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2278 		goto fail;
2279 	}
2280 
2281 	ret = wc_ecc_shared_secret_ex(ecdh->ec->key, point,
2282 				      wpabuf_put(secret, key_len), &key_len);
2283 	if (ret != MP_OKAY) {
2284 		LOG_WOLF_ERROR_FUNC(wc_ecc_shared_secret_ex, ret);
2285 		goto fail;
2286 	}
2287 
2288 done:
2289 	wc_ecc_del_point(point);
2290 	wpabuf_free(pubkey);
2291 	return secret;
2292 fail:
2293 	wpabuf_free(secret);
2294 	secret = NULL;
2295 	goto done;
2296 }
2297 
2298 
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)2299 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
2300 {
2301 	return crypto_ec_prime_len(ecdh->ec);
2302 }
2303 
crypto_ec_key_init(void)2304 static struct crypto_ec_key * crypto_ec_key_init(void)
2305 {
2306 	struct crypto_ec_key *key;
2307 
2308 	key = os_zalloc(sizeof(struct crypto_ec_key));
2309 	if (key) {
2310 		key->eckey = ecc_key_init();
2311 		/* Omit key->rng initialization because it seeds itself and thus
2312 		 * consumes entropy that may never be used. Lazy initialize when
2313 		 * necessary. */
2314 		if (!key->eckey) {
2315 			LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init);
2316 			crypto_ec_key_deinit(key);
2317 			key = NULL;
2318 		}
2319 	}
2320 	return key;
2321 }
2322 
2323 
crypto_ec_key_deinit(struct crypto_ec_key * key)2324 void crypto_ec_key_deinit(struct crypto_ec_key *key)
2325 {
2326 	if (key) {
2327 		ecc_key_deinit(key->eckey);
2328 		wc_rng_deinit(key->rng);
2329 		os_free(key);
2330 	}
2331 }
2332 
2333 
crypto_ec_key_init_rng(struct crypto_ec_key * key)2334 static WC_RNG * crypto_ec_key_init_rng(struct crypto_ec_key *key)
2335 {
2336 	if (!key->rng) {
2337 		/* Lazy init key->rng */
2338 		key->rng = wc_rng_init();
2339 		if (!key->rng)
2340 			LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
2341 	}
2342 	return key->rng;
2343 }
2344 
2345 
crypto_ec_key_parse_priv(const u8 * der,size_t der_len)2346 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
2347 {
2348 	struct crypto_ec_key *ret;
2349 	word32 idx = 0;
2350 	int err;
2351 
2352 	ret = crypto_ec_key_init();
2353 	if (!ret) {
2354 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2355 		goto fail;
2356 	}
2357 
2358 	err = wc_EccPrivateKeyDecode(der, &idx, ret->eckey, (word32) der_len);
2359 	if (err != 0) {
2360 		LOG_WOLF_ERROR_FUNC(wc_EccPrivateKeyDecode, err);
2361 		goto fail;
2362 	}
2363 
2364 	return ret;
2365 fail:
2366 	if (ret)
2367 		crypto_ec_key_deinit(ret);
2368 	return NULL;
2369 }
2370 
2371 
crypto_ec_key_group(struct crypto_ec_key * key)2372 int crypto_ec_key_group(struct crypto_ec_key *key)
2373 {
2374 
2375 	if (!key || !key->eckey || !key->eckey->dp) {
2376 		LOG_INVALID_PARAMETERS();
2377 		return -1;
2378 	}
2379 
2380 	switch (key->eckey->dp->id) {
2381 	case ECC_SECP256R1:
2382 		return 19;
2383 	case ECC_SECP384R1:
2384 		return 20;
2385 	case ECC_SECP521R1:
2386 		return 21;
2387 	case ECC_SECP192R1:
2388 		return 25;
2389 	case ECC_SECP224R1:
2390 		return 26;
2391 #ifdef HAVE_ECC_BRAINPOOL
2392 	case ECC_BRAINPOOLP224R1:
2393 		return 27;
2394 	case ECC_BRAINPOOLP256R1:
2395 		return 28;
2396 	case ECC_BRAINPOOLP384R1:
2397 		return 29;
2398 	case ECC_BRAINPOOLP512R1:
2399 		return 30;
2400 #endif /* HAVE_ECC_BRAINPOOL */
2401 	}
2402 
2403 	LOG_WOLF_ERROR_VA("Unsupported curve (id=%d) in EC key",
2404 			  key->eckey->dp->id);
2405 	return -1;
2406 }
2407 
2408 
crypto_ec_key_gen_public_key(struct crypto_ec_key * key)2409 static int crypto_ec_key_gen_public_key(struct crypto_ec_key *key)
2410 {
2411 	int err;
2412 
2413 #ifdef WOLFSSL_OLD_FIPS
2414 	err = wc_ecc_make_pub(key->eckey, NULL);
2415 #else /* WOLFSSL_OLD_FIPS */
2416 	/* Have wolfSSL generate the public key to make it available for output
2417 	 */
2418 	if (!crypto_ec_key_init_rng(key)) {
2419 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2420 		return -1;
2421 	}
2422 
2423 	err = wc_ecc_make_pub_ex(key->eckey, NULL, key->rng);
2424 #endif /* WOLFSSL_OLD_FIPS */
2425 
2426 	if (err != MP_OKAY) {
2427 		LOG_WOLF_ERROR_FUNC(wc_ecc_make_pub_ex, err);
2428 		return -1;
2429 	}
2430 
2431 	return 0;
2432 }
2433 
2434 
crypto_ec_key_get_subject_public_key(struct crypto_ec_key * key)2435 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
2436 {
2437 	int der_len;
2438 	struct wpabuf *ret = NULL;
2439 	int err;
2440 
2441 	if (!key || !key->eckey) {
2442 		LOG_INVALID_PARAMETERS();
2443 		goto fail;
2444 	}
2445 
2446 #ifdef WOLFSSL_OLD_FIPS
2447 	if (key->eckey->type == ECC_PRIVATEKEY_ONLY &&
2448 	    crypto_ec_key_gen_public_key(key) != 0) {
2449 		LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2450 		goto fail;
2451 	}
2452 #endif /* WOLFSSL_OLD_FIPS */
2453 
2454 	der_len = err = wc_EccPublicKeyToDer_ex(key->eckey, NULL, 0, 1, 1);
2455 	if (err == ECC_PRIVATEONLY_E) {
2456 		if (crypto_ec_key_gen_public_key(key) != 0) {
2457 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2458 			goto fail;
2459 		}
2460 		der_len = err = wc_EccPublicKeyToDer_ex(key->eckey, NULL, 0, 1,
2461 							1);
2462 	}
2463 	if (err <= 0) {
2464 		LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyDerSize, err);
2465 		goto fail;
2466 	}
2467 
2468 	ret = wpabuf_alloc(der_len);
2469 	if (!ret) {
2470 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2471 		goto fail;
2472 	}
2473 
2474 	err = wc_EccPublicKeyToDer_ex(key->eckey, wpabuf_mhead(ret), der_len, 1,
2475 				      1);
2476 	if (err == ECC_PRIVATEONLY_E) {
2477 		if (crypto_ec_key_gen_public_key(key) != 0) {
2478 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2479 			goto fail;
2480 		}
2481 		err = wc_EccPublicKeyToDer_ex(key->eckey, wpabuf_mhead(ret),
2482 					      der_len, 1, 1);
2483 	}
2484 	if (err <= 0) {
2485 		LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyToDer, err);
2486 		goto fail;
2487 	}
2488 	der_len = err;
2489 	wpabuf_put(ret, der_len);
2490 
2491 	return ret;
2492 
2493 fail:
2494 	wpabuf_free(ret);
2495 	return NULL;
2496 }
2497 
2498 
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)2499 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
2500 {
2501 	word32 idx = 0;
2502 	struct crypto_ec_key *ret = NULL;
2503 	int err;
2504 
2505 	ret = crypto_ec_key_init();
2506 	if (!ret) {
2507 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2508 		goto fail;
2509 	}
2510 
2511 	err = wc_EccPublicKeyDecode(der, &idx, ret->eckey, (word32) der_len);
2512 	if (err != 0) {
2513 		LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyDecode, err);
2514 		goto fail;
2515 	}
2516 
2517 	return ret;
2518 fail:
2519 	crypto_ec_key_deinit(ret);
2520 	return NULL;
2521 }
2522 
2523 
crypto_ec_key_sign(struct crypto_ec_key * key,const u8 * data,size_t len)2524 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
2525 				   size_t len)
2526 {
2527 	int der_len;
2528 	int err;
2529 	word32 w32_der_len;
2530 	struct wpabuf *ret = NULL;
2531 
2532 	if (!key || !key->eckey || !data || len == 0) {
2533 		LOG_INVALID_PARAMETERS();
2534 		goto fail;
2535 	}
2536 
2537 	if (!crypto_ec_key_init_rng(key)) {
2538 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2539 		goto fail;
2540 	}
2541 
2542 	der_len = wc_ecc_sig_size(key->eckey);
2543 	if (der_len <= 0) {
2544 		LOG_WOLF_ERROR_FUNC(wc_ecc_sig_size, der_len);
2545 		goto fail;
2546 	}
2547 
2548 	ret = wpabuf_alloc(der_len);
2549 	if (!ret) {
2550 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2551 		goto fail;
2552 	}
2553 
2554 	w32_der_len = (word32) der_len;
2555 	err = wc_ecc_sign_hash(data, len, wpabuf_mhead(ret), &w32_der_len,
2556 			       key->rng, key->eckey);
2557 	if (err != 0) {
2558 		LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash, err);
2559 		goto fail;
2560 	}
2561 	wpabuf_put(ret, w32_der_len);
2562 
2563 	return ret;
2564 fail:
2565 	wpabuf_free(ret);
2566 	return NULL;
2567 }
2568 
2569 
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)2570 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
2571 				   size_t len, const u8 *sig, size_t sig_len)
2572 {
2573 	int res = 0;
2574 
2575 	if (!key || !key->eckey || !data || len == 0 || !sig || sig_len == 0) {
2576 		LOG_INVALID_PARAMETERS();
2577 		return -1;
2578 	}
2579 
2580 	if (wc_ecc_verify_hash(sig, sig_len, data, len, &res, key->eckey) != 0)
2581 	{
2582 		LOG_WOLF_ERROR("wc_ecc_verify_hash failed");
2583 		return -1;
2584 	}
2585 
2586 	if (res != 1)
2587 		LOG_WOLF_ERROR("crypto_ec_key_verify_signature failed");
2588 
2589 	return res;
2590 }
2591 
2592 #endif /* CONFIG_ECC */
2593 
2594 #ifdef CONFIG_DPP
2595 
crypto_ec_key_get_ecprivate_key(struct crypto_ec_key * key,bool include_pub)2596 struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
2597 						bool include_pub)
2598 {
2599 	int len;
2600 	int err;
2601 	struct wpabuf *ret = NULL;
2602 
2603 	if (!key || !key->eckey) {
2604 		LOG_INVALID_PARAMETERS();
2605 		return NULL;
2606 	}
2607 
2608 #ifdef WOLFSSL_OLD_FIPS
2609 	if (key->eckey->type != ECC_PRIVATEKEY &&
2610 	    key->eckey->type != ECC_PRIVATEKEY_ONLY) {
2611 		LOG_INVALID_PARAMETERS();
2612 		return NULL;
2613 	}
2614 #endif /* WOLFSSL_OLD_FIPS */
2615 
2616 	len = err = wc_EccKeyDerSize(key->eckey, include_pub);
2617 	if (err == ECC_PRIVATEONLY_E && include_pub) {
2618 		if (crypto_ec_key_gen_public_key(key) != 0) {
2619 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2620 			return NULL;
2621 		}
2622 		len = err = wc_EccKeyDerSize(key->eckey, include_pub);
2623 	}
2624 	if (err <= 0) {
2625 		/* Exception for BAD_FUNC_ARG because higher levels blindly call
2626 		 * this function to determine if this is a private key or not.
2627 		 * BAD_FUNC_ARG most probably means that key->eckey is a public
2628 		 * key not private. */
2629 		if (err != BAD_FUNC_ARG)
2630 			LOG_WOLF_ERROR_FUNC(wc_EccKeyDerSize, err);
2631 		return NULL;
2632 	}
2633 
2634 	ret = wpabuf_alloc(len);
2635 	if (!ret) {
2636 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2637 		return NULL;
2638 	}
2639 
2640 	if (include_pub)
2641 		err = wc_EccKeyToDer(key->eckey, wpabuf_put(ret, len), len);
2642 	else
2643 		err = wc_EccPrivateKeyToDer(key->eckey, wpabuf_put(ret, len),
2644 					    len);
2645 
2646 	if (err != len) {
2647 		LOG_WOLF_ERROR_VA("%s failed with err: %d", include_pub ?
2648 				  "wc_EccKeyToDer" : "wc_EccPrivateKeyToDer",
2649 				  err);
2650 		wpabuf_free(ret);
2651 		ret = NULL;
2652 	}
2653 
2654 	return ret;
2655 }
2656 
2657 
crypto_ec_key_get_pubkey_point(struct crypto_ec_key * key,int prefix)2658 struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
2659 					       int prefix)
2660 {
2661 	int err;
2662 	word32 len = 0;
2663 	struct wpabuf *ret = NULL;
2664 
2665 	if (!key || !key->eckey) {
2666 		LOG_INVALID_PARAMETERS();
2667 		return NULL;
2668 	}
2669 
2670 	err = wc_ecc_export_x963(key->eckey, NULL, &len);
2671 	if (err != LENGTH_ONLY_E) {
2672 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2673 		goto fail;
2674 	}
2675 
2676 	ret = wpabuf_alloc(len);
2677 	if (!ret) {
2678 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2679 		goto fail;
2680 	}
2681 
2682 	err = wc_ecc_export_x963(key->eckey, wpabuf_mhead(ret), &len);
2683 	if (err == ECC_PRIVATEONLY_E) {
2684 		if (crypto_ec_key_gen_public_key(key) != 0) {
2685 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2686 			goto fail;
2687 		}
2688 		err = wc_ecc_export_x963(key->eckey, wpabuf_mhead(ret), &len);
2689 	}
2690 	if (err != MP_OKAY) {
2691 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2692 		goto fail;
2693 	}
2694 
2695 	if (!prefix)
2696 		os_memmove(wpabuf_mhead(ret), wpabuf_mhead_u8(ret) + 1,
2697 			   (size_t)--len);
2698 	wpabuf_put(ret, len);
2699 
2700 	return ret;
2701 
2702 fail:
2703 	wpabuf_free(ret);
2704 	return NULL;
2705 }
2706 
2707 
crypto_ec_key_set_pub(int group,const u8 * x,const u8 * y,size_t len)2708 struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
2709 					     const u8 *y, size_t len)
2710 {
2711 	struct crypto_ec_key *ret = NULL;
2712 	int curve_id = crypto_ec_group_2_id(group);
2713 	int err;
2714 
2715 	if (!x || !y || len == 0 || curve_id == ECC_CURVE_INVALID ||
2716 	    wc_ecc_get_curve_size_from_id(curve_id) != (int) len) {
2717 		LOG_INVALID_PARAMETERS();
2718 		return NULL;
2719 	}
2720 
2721 	ret = crypto_ec_key_init();
2722 	if (!ret) {
2723 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2724 		return NULL;
2725 	}
2726 
2727 	/* Cast necessary for FIPS API */
2728 	err = wc_ecc_import_unsigned(ret->eckey, (u8 *) x, (u8 *) y, NULL,
2729 				     curve_id);
2730 	if (err != MP_OKAY) {
2731 		LOG_WOLF_ERROR_FUNC(wc_ecc_import_unsigned, err);
2732 		crypto_ec_key_deinit(ret);
2733 		return NULL;
2734 	}
2735 
2736 	return ret;
2737 }
2738 
2739 
crypto_ec_key_cmp(struct crypto_ec_key * key1,struct crypto_ec_key * key2)2740 int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
2741 {
2742 	int ret;
2743 	struct wpabuf *key1_buf = crypto_ec_key_get_subject_public_key(key1);
2744 	struct wpabuf *key2_buf = crypto_ec_key_get_subject_public_key(key2);
2745 
2746 	if ((key1 && !key1_buf) || (key2 && !key2_buf)) {
2747 		LOG_WOLF_ERROR("crypto_ec_key_get_subject_public_key failed");
2748 		return -1;
2749 	}
2750 
2751 	ret = wpabuf_cmp(key1_buf, key2_buf);
2752 	if (ret != 0)
2753 		ret = -1; /* Default to -1 for different keys */
2754 
2755 	wpabuf_clear_free(key1_buf);
2756 	wpabuf_clear_free(key2_buf);
2757 	return ret;
2758 }
2759 
2760 
2761 /* wolfSSL doesn't have a pretty print function for keys so just print out the
2762  * PEM of the private key. */
crypto_ec_key_debug_print(const struct crypto_ec_key * key,const char * title)2763 void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
2764 			       const char *title)
2765 {
2766 	struct wpabuf * key_buf;
2767 	struct wpabuf * out = NULL;
2768 	int err;
2769 	int pem_len;
2770 
2771 	if (!key || !key->eckey) {
2772 		LOG_INVALID_PARAMETERS();
2773 		return;
2774 	}
2775 
2776 	if (key->eckey->type == ECC_PUBLICKEY)
2777 		key_buf = crypto_ec_key_get_subject_public_key(
2778 			(struct crypto_ec_key *) key);
2779 	else
2780 		key_buf = crypto_ec_key_get_ecprivate_key(
2781 			(struct crypto_ec_key *) key, 1);
2782 
2783 	if (!key_buf) {
2784 		LOG_WOLF_ERROR_VA("%s has returned NULL",
2785 				  key->eckey->type == ECC_PUBLICKEY ?
2786 				  "crypto_ec_key_get_subject_public_key" :
2787 				  "crypto_ec_key_get_ecprivate_key");
2788 		goto fail;
2789 	}
2790 
2791 	if (!title)
2792 		title = "";
2793 
2794 	err = wc_DerToPem(wpabuf_head(key_buf), wpabuf_len(key_buf), NULL, 0,
2795 			  ECC_TYPE);
2796 	if (err <= 0) {
2797 		LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
2798 		goto fail;
2799 	}
2800 	pem_len = err;
2801 
2802 	out = wpabuf_alloc(pem_len + 1);
2803 	if (!out) {
2804 		LOG_WOLF_ERROR_FUNC_NULL(wc_DerToPem);
2805 		goto fail;
2806 	}
2807 
2808 	err = wc_DerToPem(wpabuf_head(key_buf), wpabuf_len(key_buf),
2809 			  wpabuf_mhead(out), pem_len, ECC_TYPE);
2810 	if (err <= 0) {
2811 		LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
2812 		goto fail;
2813 	}
2814 
2815 	wpabuf_mhead_u8(out)[err] = '\0';
2816 	wpabuf_put(out, err + 1);
2817 	wpa_printf(MSG_DEBUG, "%s:\n%s", title,
2818 		   (const char *) wpabuf_head(out));
2819 
2820 fail:
2821 	wpabuf_clear_free(key_buf);
2822 	wpabuf_clear_free(out);
2823 }
2824 
2825 
crypto_ec_point_debug_print(const struct crypto_ec * e,const struct crypto_ec_point * p,const char * title)2826 void crypto_ec_point_debug_print(const struct crypto_ec *e,
2827 				 const struct crypto_ec_point *p,
2828 				 const char *title)
2829 {
2830 	u8 x[ECC_MAXSIZE];
2831 	u8 y[ECC_MAXSIZE];
2832 	int coord_size;
2833 	int err;
2834 
2835 	if (!p || !e) {
2836 		LOG_INVALID_PARAMETERS();
2837 		return;
2838 	}
2839 
2840 	coord_size = e->key->dp->size;
2841 
2842 	if (!title)
2843 		title = "";
2844 
2845 	err = crypto_ec_point_to_bin((struct crypto_ec *)e, p, x, y);
2846 	if (err != 0) {
2847 		LOG_WOLF_ERROR_FUNC(crypto_ec_point_to_bin, err);
2848 		return;
2849 	}
2850 
2851 	wpa_hexdump(MSG_DEBUG, title, x, coord_size);
2852 	wpa_hexdump(MSG_DEBUG, title, y, coord_size);
2853 }
2854 
2855 
crypto_ec_key_gen(int group)2856 struct crypto_ec_key * crypto_ec_key_gen(int group)
2857 {
2858 	int curve_id = crypto_ec_group_2_id(group);
2859 	int err;
2860 	struct crypto_ec_key * ret = NULL;
2861 
2862 	if (curve_id == ECC_CURVE_INVALID) {
2863 		LOG_INVALID_PARAMETERS();
2864 		return NULL;
2865 	}
2866 
2867 	ret = crypto_ec_key_init();
2868 	if (!ret) {
2869 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2870 		return NULL;
2871 	}
2872 
2873 	if (!crypto_ec_key_init_rng(ret)) {
2874 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2875 		goto fail;
2876 	}
2877 
2878 	err = wc_ecc_make_key_ex(ret->rng, 0, ret->eckey, curve_id);
2879 	if (err != MP_OKAY) {
2880 		LOG_WOLF_ERROR_FUNC(wc_ecc_make_key_ex, err);
2881 		goto fail;
2882 	}
2883 
2884 	return ret;
2885 fail:
2886 	crypto_ec_key_deinit(ret);
2887 	return NULL;
2888 }
2889 
2890 
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)2891 int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
2892 				       const u8 *data, size_t len,
2893 				       const u8 *r, size_t r_len,
2894 				       const u8 *s, size_t s_len)
2895 {
2896 	int err;
2897 	u8 sig[ECC_MAX_SIG_SIZE];
2898 	word32 sig_len = ECC_MAX_SIG_SIZE;
2899 
2900 	if (!key || !key->eckey || !data || !len || !r || !r_len ||
2901 	    !s || !s_len) {
2902 		LOG_INVALID_PARAMETERS();
2903 		return -1;
2904 	}
2905 
2906 	err = wc_ecc_rs_raw_to_sig(r, r_len, s, s_len, sig, &sig_len);
2907 	if (err != MP_OKAY) {
2908 		LOG_WOLF_ERROR_FUNC(wc_ecc_rs_raw_to_sig, err);
2909 		return -1;
2910 	}
2911 
2912 	return crypto_ec_key_verify_signature(key, data, len, sig, sig_len);
2913 }
2914 
2915 
crypto_ec_key_get_public_key(struct crypto_ec_key * key)2916 struct crypto_ec_point * crypto_ec_key_get_public_key(struct crypto_ec_key *key)
2917 {
2918 	ecc_point *point = NULL;
2919 	int err;
2920 	u8 *der = NULL;
2921 	word32 der_len = 0;
2922 
2923 	if (!key || !key->eckey || !key->eckey->dp) {
2924 		LOG_INVALID_PARAMETERS();
2925 		goto fail;
2926 	}
2927 
2928 	err = wc_ecc_export_x963(key->eckey, NULL, &der_len);
2929 	if (err != LENGTH_ONLY_E) {
2930 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2931 		goto fail;
2932 	}
2933 
2934 	der = os_malloc(der_len);
2935 	if (!der) {
2936 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
2937 		goto fail;
2938 	}
2939 
2940 	err = wc_ecc_export_x963(key->eckey, der, &der_len);
2941 	if (err == ECC_PRIVATEONLY_E) {
2942 		if (crypto_ec_key_gen_public_key(key) != 0) {
2943 			LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2944 			goto fail;
2945 		}
2946 		err = wc_ecc_export_x963(key->eckey, der, &der_len);
2947 	}
2948 	if (err != MP_OKAY) {
2949 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2950 		goto fail;
2951 	}
2952 
2953 	point = wc_ecc_new_point();
2954 	if (!point) {
2955 		LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
2956 		goto fail;
2957 	}
2958 
2959 	err = wc_ecc_import_point_der(der, der_len, key->eckey->idx, point);
2960 	if (err != MP_OKAY) {
2961 		LOG_WOLF_ERROR_FUNC(wc_ecc_import_point_der, err);
2962 		goto fail;
2963 	}
2964 
2965 	os_free(der);
2966 	return (struct crypto_ec_point *) point;
2967 
2968 fail:
2969 	os_free(der);
2970 	if (point)
2971 		wc_ecc_del_point(point);
2972 	return NULL;
2973 }
2974 
2975 
crypto_ec_key_get_private_key(struct crypto_ec_key * key)2976 struct crypto_bignum * crypto_ec_key_get_private_key(struct crypto_ec_key *key)
2977 {
2978 	u8 priv[ECC_MAXSIZE];
2979 	word32 priv_len = ECC_MAXSIZE;
2980 #ifdef WOLFSSL_OLD_FIPS
2981 	/* Needed to be compliant with the old API */
2982 	u8 qx[ECC_MAXSIZE];
2983 	word32 qx_len = ECC_MAXSIZE;
2984 	u8 qy[ECC_MAXSIZE];
2985 	word32 qy_len = ECC_MAXSIZE;
2986 #endif /* WOLFSSL_OLD_FIPS */
2987 	struct crypto_bignum *ret = NULL;
2988 	int err;
2989 
2990 	if (!key || !key->eckey) {
2991 		LOG_INVALID_PARAMETERS();
2992 		return NULL;
2993 	}
2994 
2995 #ifndef WOLFSSL_OLD_FIPS
2996 	err = wc_ecc_export_private_raw(key->eckey, NULL, NULL, NULL, NULL,
2997 					priv, &priv_len);
2998 #else /* WOLFSSL_OLD_FIPS */
2999 	err = wc_ecc_export_private_raw(key->eckey, qx, &qx_len, qy, &qy_len,
3000 					priv, &priv_len);
3001 #endif /* WOLFSSL_OLD_FIPS */
3002 	if (err != MP_OKAY) {
3003 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_private_raw, err);
3004 		return NULL;
3005 	}
3006 
3007 	ret = crypto_bignum_init_set(priv, priv_len);
3008 	forced_memzero(priv, priv_len);
3009 	return ret;
3010 }
3011 
3012 
crypto_ec_key_sign_r_s(struct crypto_ec_key * key,const u8 * data,size_t len)3013 struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
3014 				       const u8 *data, size_t len)
3015 {
3016 	int err;
3017 	u8 success = 0;
3018 	mp_int r;
3019 	mp_int s;
3020 	u8 rs_init = 0;
3021 	int sz;
3022 	struct wpabuf * ret = NULL;
3023 
3024 	if (!key || !key->eckey || !key->eckey->dp || !data || !len) {
3025 		LOG_INVALID_PARAMETERS();
3026 		return NULL;
3027 	}
3028 
3029 	sz = key->eckey->dp->size;
3030 
3031 	if (!crypto_ec_key_init_rng(key)) {
3032 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
3033 		goto fail;
3034 	}
3035 
3036 	err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL);
3037 	if (err != MP_OKAY) {
3038 		LOG_WOLF_ERROR_FUNC(mp_init_multi, err);
3039 		goto fail;
3040 	}
3041 	rs_init = 1;
3042 
3043 	err = wc_ecc_sign_hash_ex(data, len, key->rng, key->eckey, &r, &s);
3044 	if (err != MP_OKAY) {
3045 		LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash_ex, err);
3046 		goto fail;
3047 	}
3048 
3049 	if (mp_unsigned_bin_size(&r) > sz || mp_unsigned_bin_size(&s) > sz) {
3050 		LOG_WOLF_ERROR_VA("Unexpected size of r or s (%d %d %d)", sz,
3051 				  mp_unsigned_bin_size(&r),
3052 				  mp_unsigned_bin_size(&s));
3053 		goto fail;
3054 	}
3055 
3056 	ret = wpabuf_alloc(2 * sz);
3057 	if (!ret) {
3058 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3059 		goto fail;
3060 	}
3061 
3062 	err = mp_to_unsigned_bin_len(&r, wpabuf_put(ret, sz), sz);
3063 	if (err == MP_OKAY)
3064 		err = mp_to_unsigned_bin_len(&s, wpabuf_put(ret, sz), sz);
3065 	if (err != MP_OKAY) {
3066 		LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash_ex, err);
3067 		goto fail;
3068 	}
3069 
3070 	success = 1;
3071 fail:
3072 	if (rs_init) {
3073 		mp_free(&r);
3074 		mp_free(&s);
3075 	}
3076 	if (!success) {
3077 		wpabuf_free(ret);
3078 		ret = NULL;
3079 	}
3080 
3081 	return ret;
3082 }
3083 
3084 
3085 struct crypto_ec_key *
crypto_ec_key_set_pub_point(struct crypto_ec * e,const struct crypto_ec_point * pub)3086 crypto_ec_key_set_pub_point(struct crypto_ec *e,
3087 			    const struct crypto_ec_point *pub)
3088 {
3089 	struct crypto_ec_key  *ret = NULL;
3090 	int err;
3091 	byte *buf = NULL;
3092 	word32 buf_len = 0;
3093 
3094 	if (!e || !pub) {
3095 		LOG_INVALID_PARAMETERS();
3096 		return NULL;
3097 	}
3098 
3099 	/* Export to DER to not mess with wolfSSL internals */
3100 	err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(e->curve_id),
3101 				      (ecc_point *) pub, NULL, &buf_len);
3102 	if (err != LENGTH_ONLY_E || !buf_len) {
3103 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_point_der, err);
3104 		goto fail;
3105 	}
3106 
3107 	buf = os_malloc(buf_len);
3108 	if (!buf) {
3109 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3110 		goto fail;
3111 	}
3112 
3113 	err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(e->curve_id),
3114 			(ecc_point *) pub, buf, &buf_len);
3115 	if (err != MP_OKAY) {
3116 		LOG_WOLF_ERROR_FUNC(wc_ecc_export_point_der, err);
3117 		goto fail;
3118 	}
3119 
3120 	ret = crypto_ec_key_init();
3121 	if (!ret) {
3122 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
3123 		goto fail;
3124 	}
3125 
3126 	err = wc_ecc_import_x963_ex(buf, buf_len, ret->eckey, e->curve_id);
3127 	if (err != MP_OKAY) {
3128 		LOG_WOLF_ERROR_FUNC(wc_ecc_import_x963_ex, err);
3129 		goto fail;
3130 	}
3131 
3132 	os_free(buf);
3133 	return ret;
3134 
3135 fail:
3136 	os_free(buf);
3137 	crypto_ec_key_deinit(ret);
3138 	return NULL;
3139 }
3140 
3141 
crypto_pkcs7_get_certificates(const struct wpabuf * pkcs7)3142 struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
3143 {
3144 	PKCS7 *p7 = NULL;
3145 	struct wpabuf *ret = NULL;
3146 	int err = 0;
3147 	int total_sz = 0;
3148 	int i;
3149 
3150 	if (!pkcs7) {
3151 		LOG_INVALID_PARAMETERS();
3152 		return NULL;
3153 	}
3154 
3155 	p7 = wc_PKCS7_New(NULL, INVALID_DEVID);
3156 	if (!p7) {
3157 		LOG_WOLF_ERROR_FUNC_NULL(wc_PKCS7_New);
3158 		return NULL;
3159 	}
3160 
3161 	err = wc_PKCS7_VerifySignedData(p7, (byte *) wpabuf_head(pkcs7),
3162 					wpabuf_len(pkcs7));
3163 	if (err != 0) {
3164 		LOG_WOLF_ERROR_FUNC(wc_PKCS7_VerifySignedData, err);
3165 		wc_PKCS7_Free(p7);
3166 		goto fail;
3167 	}
3168 
3169 	/* Need to access p7 members directly */
3170 	for (i = 0; i < MAX_PKCS7_CERTS; i++) {
3171 		if (p7->certSz[i] == 0)
3172 			continue;
3173 		err = wc_DerToPem(p7->cert[i], p7->certSz[i], NULL, 0,
3174 				  CERT_TYPE);
3175 		if (err > 0) {
3176 			total_sz += err;
3177 		} else {
3178 			LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
3179 			goto fail;
3180 		}
3181 	}
3182 
3183 	if (total_sz == 0) {
3184 		LOG_WOLF_ERROR("No certificates found in PKCS7 input");
3185 		goto fail;
3186 	}
3187 
3188 	ret = wpabuf_alloc(total_sz);
3189 	if (!ret) {
3190 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3191 		goto fail;
3192 	}
3193 
3194 	/* Need to access p7 members directly */
3195 	for (i = 0; i < MAX_PKCS7_CERTS; i++) {
3196 		if (p7->certSz[i] == 0)
3197 			continue;
3198 		/* Not using wpabuf_put() here so that wpabuf_overflow() isn't
3199 		 * called in case of a size mismatch. wc_DerToPem() checks if
3200 		 * the output is large enough internally. */
3201 		err = wc_DerToPem(p7->cert[i], p7->certSz[i],
3202 				  wpabuf_mhead_u8(ret) + wpabuf_len(ret),
3203 				  wpabuf_tailroom(ret),
3204 				  CERT_TYPE);
3205 		if (err > 0) {
3206 			wpabuf_put(ret, err);
3207 		} else {
3208 			LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
3209 			wpabuf_free(ret);
3210 			ret = NULL;
3211 			goto fail;
3212 		}
3213 	}
3214 
3215 fail:
3216 	if (p7)
3217 		wc_PKCS7_Free(p7);
3218 	return ret;
3219 }
3220 
3221 
3222 /* BEGIN Certificate Signing Request (CSR) APIs */
3223 
3224 enum cert_type {
3225 	cert_type_none = 0,
3226 	cert_type_decoded_cert,
3227 	cert_type_cert,
3228 };
3229 
3230 struct crypto_csr {
3231 	union {
3232 		/* For parsed csr should be read-only for higher levels */
3233 		DecodedCert dc;
3234 		Cert c; /* For generating a csr */
3235 	} req;
3236 	enum cert_type type;
3237 	struct crypto_ec_key *pubkey;
3238 };
3239 
3240 
3241 /* 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)3242 static void crypto_csr_init_type(struct crypto_csr *csr, enum cert_type type,
3243 				 const byte *source, word32 in_sz)
3244 {
3245 	int err;
3246 
3247 	if (csr->type == type)
3248 		return; /* Already correct type */
3249 
3250 	switch (csr->type) {
3251 	case cert_type_decoded_cert:
3252 		wc_FreeDecodedCert(&csr->req.dc);
3253 		break;
3254 	case cert_type_cert:
3255 #ifdef WOLFSSL_CERT_GEN_CACHE
3256 		wc_SetCert_Free(&csr->req.c);
3257 #endif /* WOLFSSL_CERT_GEN_CACHE */
3258 		break;
3259 	case cert_type_none:
3260 		break;
3261 	}
3262 
3263 	switch (type) {
3264 	case cert_type_decoded_cert:
3265 		wc_InitDecodedCert(&csr->req.dc, source, in_sz, NULL);
3266 		break;
3267 	case cert_type_cert:
3268 		err = wc_InitCert(&csr->req.c);
3269 		if (err != 0)
3270 			LOG_WOLF_ERROR_FUNC(wc_InitCert, err);
3271 		break;
3272 	case cert_type_none:
3273 		break;
3274 	}
3275 
3276 	csr->type = type;
3277 }
3278 
3279 
crypto_csr_init(void)3280 struct crypto_csr * crypto_csr_init(void)
3281 {
3282 	struct crypto_csr *ret = os_malloc(sizeof(struct crypto_csr));
3283 
3284 	if (!ret) {
3285 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3286 		return NULL;
3287 	}
3288 
3289 	ret->type = cert_type_none;
3290 	crypto_csr_init_type(ret, cert_type_cert, NULL, 0);
3291 	ret->pubkey = NULL;
3292 
3293 	return ret;
3294 }
3295 
3296 
crypto_csr_deinit(struct crypto_csr * csr)3297 void crypto_csr_deinit(struct crypto_csr *csr)
3298 {
3299 	if (csr) {
3300 		crypto_csr_init_type(csr, cert_type_none, NULL, 0);
3301 		crypto_ec_key_deinit(csr->pubkey);
3302 		os_free(csr);
3303 	}
3304 }
3305 
3306 
crypto_csr_set_ec_public_key(struct crypto_csr * csr,struct crypto_ec_key * key)3307 int crypto_csr_set_ec_public_key(struct crypto_csr *csr,
3308 				 struct crypto_ec_key *key)
3309 {
3310 	struct wpabuf *der = NULL;
3311 
3312 	if (!csr || !key || !key->eckey) {
3313 		LOG_INVALID_PARAMETERS();
3314 		return -1;
3315 	}
3316 
3317 	if (csr->pubkey) {
3318 		crypto_ec_key_deinit(csr->pubkey);
3319 		csr->pubkey = NULL;
3320 	}
3321 
3322 	/* Create copy of key to mitigate use-after-free errors */
3323 	der = crypto_ec_key_get_subject_public_key(key);
3324 	if (!der) {
3325 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_get_subject_public_key);
3326 		return -1;
3327 	}
3328 
3329 	csr->pubkey = crypto_ec_key_parse_pub(wpabuf_head(der),
3330 					      wpabuf_len(der));
3331 	wpabuf_free(der);
3332 	if (!csr->pubkey) {
3333 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_parse_pub);
3334 		return -1;
3335 	}
3336 
3337 	return 0;
3338 }
3339 
3340 
crypto_csr_set_name(struct crypto_csr * csr,enum crypto_csr_name type,const char * name)3341 int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
3342 			const char *name)
3343 {
3344 	int name_len;
3345 	char *dest;
3346 
3347 	if (!csr || !name) {
3348 		LOG_INVALID_PARAMETERS();
3349 		return -1;
3350 	}
3351 
3352 	if (csr->type != cert_type_cert) {
3353 		LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3354 		return -1;
3355 	}
3356 
3357 	name_len = os_strlen(name);
3358 	if (name_len >= CTC_NAME_SIZE) {
3359 		LOG_WOLF_ERROR("name input too long");
3360 		return -1;
3361 	}
3362 
3363 	switch (type) {
3364 	case CSR_NAME_CN:
3365 		dest = csr->req.c.subject.commonName;
3366 		break;
3367 	case CSR_NAME_SN:
3368 		dest = csr->req.c.subject.sur;
3369 		break;
3370 	case CSR_NAME_C:
3371 		dest = csr->req.c.subject.country;
3372 		break;
3373 	case CSR_NAME_O:
3374 		dest = csr->req.c.subject.org;
3375 		break;
3376 	case CSR_NAME_OU:
3377 		dest = csr->req.c.subject.unit;
3378 		break;
3379 	default:
3380 		LOG_INVALID_PARAMETERS();
3381 		return -1;
3382 	}
3383 
3384 	os_memcpy(dest, name, name_len);
3385 	dest[name_len] = '\0';
3386 
3387 	return 0;
3388 }
3389 
3390 
crypto_csr_set_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,int attr_type,const u8 * value,size_t len)3391 int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
3392 			     int attr_type, const u8 *value, size_t len)
3393 {
3394 	if (!csr || attr_type != ASN1_TAG_UTF8STRING || !value ||
3395 	    len >= CTC_NAME_SIZE) {
3396 		LOG_INVALID_PARAMETERS();
3397 		return -1;
3398 	}
3399 
3400 	if (csr->type != cert_type_cert) {
3401 		LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3402 		return -1;
3403 	}
3404 
3405 	switch (attr) {
3406 	case CSR_ATTR_CHALLENGE_PASSWORD:
3407 		os_memcpy(csr->req.c.challengePw, value, len);
3408 		csr->req.c.challengePw[len] = '\0';
3409 		break;
3410 	default:
3411 		return -1;
3412 	}
3413 
3414 	return 0;
3415 }
3416 
3417 
crypto_csr_get_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,size_t * len,int * type)3418 const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
3419 				    enum crypto_csr_attr attr,
3420 				    size_t *len, int *type)
3421 {
3422 	if (!csr || !len || !type) {
3423 		LOG_INVALID_PARAMETERS();
3424 		return NULL;;
3425 	}
3426 
3427 	switch (attr) {
3428 	case CSR_ATTR_CHALLENGE_PASSWORD:
3429 		switch (csr->type) {
3430 		case cert_type_decoded_cert:
3431 			*type = ASN1_TAG_UTF8STRING;
3432 			*len = csr->req.dc.cPwdLen;
3433 			return (const u8 *) csr->req.dc.cPwd;
3434 		case cert_type_cert:
3435 			*type = ASN1_TAG_UTF8STRING;
3436 			*len = os_strlen(csr->req.c.challengePw);
3437 			return (const u8 *) csr->req.c.challengePw;
3438 		case cert_type_none:
3439 			return NULL;
3440 		}
3441 		break;
3442 	}
3443 	return NULL;
3444 }
3445 
3446 
crypto_csr_sign(struct crypto_csr * csr,struct crypto_ec_key * key,enum crypto_hash_alg algo)3447 struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
3448 				struct crypto_ec_key *key,
3449 				enum crypto_hash_alg algo)
3450 {
3451 	int err;
3452 	int len;
3453 	u8 *buf = NULL;
3454 	int buf_len;
3455 	struct wpabuf *ret = NULL;
3456 
3457 	if (!csr || !key || !key->eckey) {
3458 		LOG_INVALID_PARAMETERS();
3459 		return NULL;
3460 	}
3461 
3462 	if (csr->type != cert_type_cert) {
3463 		LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3464 		return NULL;
3465 	}
3466 
3467 	if (!crypto_ec_key_init_rng(key)) {
3468 		LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
3469 		return NULL;
3470 	}
3471 
3472 	switch (algo) {
3473 	case CRYPTO_HASH_ALG_SHA256:
3474 		csr->req.c.sigType = CTC_SHA256wECDSA;
3475 		break;
3476 	case CRYPTO_HASH_ALG_SHA384:
3477 		csr->req.c.sigType = CTC_SHA384wECDSA;
3478 		break;
3479 	case CRYPTO_HASH_ALG_SHA512:
3480 		csr->req.c.sigType = CTC_SHA512wECDSA;
3481 		break;
3482 	default:
3483 		LOG_INVALID_PARAMETERS();
3484 		return NULL;
3485 	}
3486 
3487 	/* Pass in large value that is guaranteed to be larger than the
3488 	 * necessary buffer */
3489 	err = wc_MakeCertReq(&csr->req.c, NULL, 100000, NULL,
3490 			     csr->pubkey->eckey);
3491 	if (err <= 0) {
3492 		LOG_WOLF_ERROR_FUNC(wc_MakeCertReq, err);
3493 		goto fail;
3494 	}
3495 	len = err;
3496 
3497 	buf_len = len + MAX_SEQ_SZ * 2 + MAX_ENCODED_SIG_SZ;
3498 	buf = os_malloc(buf_len);
3499 	if (!buf) {
3500 		LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3501 		goto fail;
3502 	}
3503 
3504 	err = wc_MakeCertReq(&csr->req.c, buf, buf_len, NULL,
3505 			     csr->pubkey->eckey);
3506 	if (err <= 0) {
3507 		LOG_WOLF_ERROR_FUNC(wc_MakeCertReq, err);
3508 		goto fail;
3509 	}
3510 	len = err;
3511 
3512 	err = wc_SignCert(len, csr->req.c.sigType, buf, buf_len, NULL,
3513 			  key->eckey, key->rng);
3514 	if (err <= 0) {
3515 		LOG_WOLF_ERROR_FUNC(wc_SignCert, err);
3516 		goto fail;
3517 	}
3518 	len = err;
3519 
3520 	ret = wpabuf_alloc_copy(buf, len);
3521 	if (!ret) {
3522 		LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc_copy);
3523 		goto fail;
3524 	}
3525 
3526 fail:
3527 	os_free(buf);
3528 	return ret;
3529 }
3530 
3531 
crypto_csr_verify(const struct wpabuf * req)3532 struct crypto_csr * crypto_csr_verify(const struct wpabuf *req)
3533 {
3534 	struct crypto_csr *csr = NULL;
3535 	int err;
3536 
3537 	if (!req) {
3538 		LOG_INVALID_PARAMETERS();
3539 		return NULL;
3540 	}
3541 
3542 	csr = crypto_csr_init();
3543 	if (!csr) {
3544 		LOG_WOLF_ERROR_FUNC_NULL(crypto_csr_init);
3545 		goto fail;
3546 	}
3547 
3548 	crypto_csr_init_type(csr, cert_type_decoded_cert,
3549 			     wpabuf_head(req), wpabuf_len(req));
3550 	err = wc_ParseCert(&csr->req.dc, CERTREQ_TYPE, VERIFY, NULL);
3551 	if (err != 0) {
3552 		LOG_WOLF_ERROR_FUNC(wc_ParseCert, err);
3553 		goto fail;
3554 	}
3555 
3556 	return csr;
3557 fail:
3558 	crypto_csr_deinit(csr);
3559 	return NULL;
3560 }
3561 
3562 /* END Certificate Signing Request (CSR) APIs */
3563 
3564 #endif /* CONFIG_DPP */
3565 
3566 
crypto_unload(void)3567 void crypto_unload(void)
3568 {
3569 }
3570