• 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 
14 /* wolfSSL headers */
15 #include <wolfssl/options.h>
16 #include <wolfssl/wolfcrypt/md4.h>
17 #include <wolfssl/wolfcrypt/md5.h>
18 #include <wolfssl/wolfcrypt/sha.h>
19 #include <wolfssl/wolfcrypt/sha256.h>
20 #include <wolfssl/wolfcrypt/sha512.h>
21 #include <wolfssl/wolfcrypt/hmac.h>
22 #include <wolfssl/wolfcrypt/pwdbased.h>
23 #include <wolfssl/wolfcrypt/arc4.h>
24 #include <wolfssl/wolfcrypt/des3.h>
25 #include <wolfssl/wolfcrypt/aes.h>
26 #include <wolfssl/wolfcrypt/dh.h>
27 #include <wolfssl/wolfcrypt/cmac.h>
28 #include <wolfssl/wolfcrypt/ecc.h>
29 #include <wolfssl/wolfcrypt/asn_public.h>
30 #include <wolfssl/wolfcrypt/error-crypt.h>
31 #include <wolfssl/openssl/bn.h>
32 
33 
34 #ifndef CONFIG_FIPS
35 
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)36 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
37 {
38 	Md4 md4;
39 	size_t i;
40 
41 	if (TEST_FAIL())
42 		return -1;
43 
44 	wc_InitMd4(&md4);
45 
46 	for (i = 0; i < num_elem; i++)
47 		wc_Md4Update(&md4, addr[i], len[i]);
48 
49 	wc_Md4Final(&md4, mac);
50 
51 	return 0;
52 }
53 
54 
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)55 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
56 {
57 	wc_Md5 md5;
58 	size_t i;
59 
60 	if (TEST_FAIL())
61 		return -1;
62 
63 	wc_InitMd5(&md5);
64 
65 	for (i = 0; i < num_elem; i++)
66 		wc_Md5Update(&md5, addr[i], len[i]);
67 
68 	wc_Md5Final(&md5, mac);
69 
70 	return 0;
71 }
72 
73 #endif /* CONFIG_FIPS */
74 
75 
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)76 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
77 {
78 	wc_Sha sha;
79 	size_t i;
80 
81 	if (TEST_FAIL())
82 		return -1;
83 
84 	wc_InitSha(&sha);
85 
86 	for (i = 0; i < num_elem; i++)
87 		wc_ShaUpdate(&sha, addr[i], len[i]);
88 
89 	wc_ShaFinal(&sha, mac);
90 	wc_ShaFree(&sha);
91 
92 	return 0;
93 }
94 
95 
96 #ifndef NO_SHA256_WRAPPER
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)97 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
98 		  u8 *mac)
99 {
100 	wc_Sha256 sha256;
101 	size_t i;
102 
103 	if (TEST_FAIL())
104 		return -1;
105 
106 	wc_InitSha256(&sha256);
107 
108 	for (i = 0; i < num_elem; i++)
109 		wc_Sha256Update(&sha256, addr[i], len[i]);
110 
111 	wc_Sha256Final(&sha256, mac);
112 	wc_Sha256Free(&sha256);
113 
114 	return 0;
115 }
116 #endif /* NO_SHA256_WRAPPER */
117 
118 
119 #ifdef CONFIG_SHA384
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)120 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
121 		  u8 *mac)
122 {
123 	wc_Sha384 sha384;
124 	size_t i;
125 
126 	if (TEST_FAIL())
127 		return -1;
128 
129 	wc_InitSha384(&sha384);
130 
131 	for (i = 0; i < num_elem; i++)
132 		wc_Sha384Update(&sha384, addr[i], len[i]);
133 
134 	wc_Sha384Final(&sha384, mac);
135 	wc_Sha384Free(&sha384);
136 
137 	return 0;
138 }
139 #endif /* CONFIG_SHA384 */
140 
141 
142 #ifdef CONFIG_SHA512
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)143 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
144 		  u8 *mac)
145 {
146 	wc_Sha512 sha512;
147 	size_t i;
148 
149 	if (TEST_FAIL())
150 		return -1;
151 
152 	wc_InitSha512(&sha512);
153 
154 	for (i = 0; i < num_elem; i++)
155 		wc_Sha512Update(&sha512, addr[i], len[i]);
156 
157 	wc_Sha512Final(&sha512, mac);
158 	wc_Sha512Free(&sha512);
159 
160 	return 0;
161 }
162 #endif /* CONFIG_SHA512 */
163 
164 
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)165 static int wolfssl_hmac_vector(int type, const u8 *key,
166 			       size_t key_len, size_t num_elem,
167 			       const u8 *addr[], const size_t *len, u8 *mac,
168 			       unsigned int mdlen)
169 {
170 	Hmac hmac;
171 	size_t i;
172 
173 	(void) mdlen;
174 
175 	if (TEST_FAIL())
176 		return -1;
177 
178 	if (wc_HmacInit(&hmac, NULL, INVALID_DEVID) != 0 ||
179 	    wc_HmacSetKey(&hmac, type, key, (word32) key_len) != 0)
180 		return -1;
181 	for (i = 0; i < num_elem; i++)
182 		if (wc_HmacUpdate(&hmac, addr[i], len[i]) != 0)
183 			return -1;
184 	if (wc_HmacFinal(&hmac, mac) != 0)
185 		return -1;
186 	wc_HmacFree(&hmac);
187 
188 	return 0;
189 }
190 
191 
192 #ifndef CONFIG_FIPS
193 
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)194 int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
195 		    const u8 *addr[], const size_t *len, u8 *mac)
196 {
197 	return wolfssl_hmac_vector(WC_MD5, key, key_len, num_elem, addr, len,
198 				   mac, 16);
199 }
200 
201 
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)202 int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
203 	     u8 *mac)
204 {
205 	return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
206 }
207 
208 #endif /* CONFIG_FIPS */
209 
210 
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)211 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
212 		     const u8 *addr[], const size_t *len, u8 *mac)
213 {
214 	return wolfssl_hmac_vector(WC_SHA, key, key_len, num_elem, addr, len,
215 				   mac, 20);
216 }
217 
218 
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)219 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
220 	      u8 *mac)
221 {
222 	return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
223 }
224 
225 
226 #ifdef CONFIG_SHA256
227 
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)228 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
229 		       const u8 *addr[], const size_t *len, u8 *mac)
230 {
231 	return wolfssl_hmac_vector(WC_SHA256, key, key_len, num_elem, addr, len,
232 				   mac, 32);
233 }
234 
235 
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)236 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
237 		size_t data_len, u8 *mac)
238 {
239 	return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
240 }
241 
242 #endif /* CONFIG_SHA256 */
243 
244 
245 #ifdef CONFIG_SHA384
246 
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)247 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
248 		       const u8 *addr[], const size_t *len, u8 *mac)
249 {
250 	return wolfssl_hmac_vector(WC_SHA384, key, key_len, num_elem, addr, len,
251 				   mac, 48);
252 }
253 
254 
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)255 int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
256 		size_t data_len, u8 *mac)
257 {
258 	return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
259 }
260 
261 #endif /* CONFIG_SHA384 */
262 
263 
264 #ifdef CONFIG_SHA512
265 
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)266 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
267 		       const u8 *addr[], const size_t *len, u8 *mac)
268 {
269 	return wolfssl_hmac_vector(WC_SHA512, key, key_len, num_elem, addr, len,
270 				   mac, 64);
271 }
272 
273 
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)274 int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
275 		size_t data_len, u8 *mac)
276 {
277 	return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
278 }
279 
280 #endif /* CONFIG_SHA512 */
281 
282 
pbkdf2_sha1(const char * passphrase,const u8 * ssid,size_t ssid_len,int iterations,u8 * buf,size_t buflen)283 int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
284 		int iterations, u8 *buf, size_t buflen)
285 {
286 	int ret;
287 
288 	ret = wc_PBKDF2(buf, (const byte *) passphrase, os_strlen(passphrase),
289 			ssid, ssid_len, iterations, buflen, WC_SHA);
290 	if (ret != 0) {
291 		if (ret == HMAC_MIN_KEYLEN_E) {
292 			wpa_printf(MSG_ERROR,
293 				   "wolfSSL: Password is too short. Make sure your password is at least %d characters long. This is a requirement for FIPS builds.",
294 				   HMAC_FIPS_MIN_KEY);
295 		}
296 		return -1;
297 	}
298 	return 0;
299 }
300 
301 
302 #ifdef CONFIG_DES
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)303 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
304 {
305 	Des des;
306 	u8  pkey[8], next, tmp;
307 	int i;
308 
309 	/* Add parity bits to the key */
310 	next = 0;
311 	for (i = 0; i < 7; i++) {
312 		tmp = key[i];
313 		pkey[i] = (tmp >> i) | next | 1;
314 		next = tmp << (7 - i);
315 	}
316 	pkey[i] = next | 1;
317 
318 	wc_Des_SetKey(&des, pkey, NULL, DES_ENCRYPTION);
319 	wc_Des_EcbEncrypt(&des, cypher, clear, DES_BLOCK_SIZE);
320 
321 	return 0;
322 }
323 #endif /* CONFIG_DES */
324 
325 
aes_encrypt_init(const u8 * key,size_t len)326 void * aes_encrypt_init(const u8 *key, size_t len)
327 {
328 	Aes *aes;
329 
330 	if (TEST_FAIL())
331 		return NULL;
332 
333 	aes = os_malloc(sizeof(Aes));
334 	if (!aes)
335 		return NULL;
336 
337 	if (wc_AesSetKey(aes, key, len, NULL, AES_ENCRYPTION) < 0) {
338 		os_free(aes);
339 		return NULL;
340 	}
341 
342 	return aes;
343 }
344 
345 
aes_encrypt(void * ctx,const u8 * plain,u8 * crypt)346 int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
347 {
348 	wc_AesEncryptDirect(ctx, crypt, plain);
349 	return 0;
350 }
351 
352 
aes_encrypt_deinit(void * ctx)353 void aes_encrypt_deinit(void *ctx)
354 {
355 	os_free(ctx);
356 }
357 
358 
aes_decrypt_init(const u8 * key,size_t len)359 void * aes_decrypt_init(const u8 *key, size_t len)
360 {
361 	Aes *aes;
362 
363 	if (TEST_FAIL())
364 		return NULL;
365 
366 	aes = os_malloc(sizeof(Aes));
367 	if (!aes)
368 		return NULL;
369 
370 	if (wc_AesSetKey(aes, key, len, NULL, AES_DECRYPTION) < 0) {
371 		os_free(aes);
372 		return NULL;
373 	}
374 
375 	return aes;
376 }
377 
378 
aes_decrypt(void * ctx,const u8 * crypt,u8 * plain)379 int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
380 {
381 	wc_AesDecryptDirect(ctx, plain, crypt);
382 	return 0;
383 }
384 
385 
aes_decrypt_deinit(void * ctx)386 void aes_decrypt_deinit(void *ctx)
387 {
388 	os_free(ctx);
389 }
390 
391 
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)392 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
393 {
394 	Aes aes;
395 	int ret;
396 
397 	if (TEST_FAIL())
398 		return -1;
399 
400 	ret = wc_AesSetKey(&aes, key, 16, iv, AES_ENCRYPTION);
401 	if (ret != 0)
402 		return -1;
403 
404 	ret = wc_AesCbcEncrypt(&aes, data, data, data_len);
405 	if (ret != 0)
406 		return -1;
407 	return 0;
408 }
409 
410 
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)411 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
412 {
413 	Aes aes;
414 	int ret;
415 
416 	if (TEST_FAIL())
417 		return -1;
418 
419 	ret = wc_AesSetKey(&aes, key, 16, iv, AES_DECRYPTION);
420 	if (ret != 0)
421 		return -1;
422 
423 	ret = wc_AesCbcDecrypt(&aes, data, data, data_len);
424 	if (ret != 0)
425 		return -1;
426 	return 0;
427 }
428 
429 
430 #ifndef CONFIG_FIPS
431 #ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP
aes_wrap(const u8 * kek,size_t kek_len,int n,const u8 * plain,u8 * cipher)432 int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
433 {
434 #ifdef HAVE_AES_KEYWRAP
435 	int ret;
436 
437 	if (TEST_FAIL())
438 		return -1;
439 
440 	ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8,
441 			    NULL);
442 	return ret != (n + 1) * 8 ? -1 : 0;
443 #else /* HAVE_AES_KEYWRAP */
444 	return -1;
445 #endif /* HAVE_AES_KEYWRAP */
446 }
447 
448 
aes_unwrap(const u8 * kek,size_t kek_len,int n,const u8 * cipher,u8 * plain)449 int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
450 	       u8 *plain)
451 {
452 #ifdef HAVE_AES_KEYWRAP
453 	int ret;
454 
455 	if (TEST_FAIL())
456 		return -1;
457 
458 	ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8,
459 			      NULL);
460 	return ret != n * 8 ? -1 : 0;
461 #else /* HAVE_AES_KEYWRAP */
462 	return -1;
463 #endif /* HAVE_AES_KEYWRAP */
464 }
465 #endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */
466 #endif /* CONFIG_FIPS */
467 
468 
469 #ifndef CONFIG_NO_RC4
rc4_skip(const u8 * key,size_t keylen,size_t skip,u8 * data,size_t data_len)470 int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data,
471 	     size_t data_len)
472 {
473 #ifndef NO_RC4
474 	Arc4 arc4;
475 	unsigned char skip_buf[16];
476 
477 	wc_Arc4SetKey(&arc4, key, keylen);
478 
479 	while (skip >= sizeof(skip_buf)) {
480 		size_t len = skip;
481 
482 		if (len > sizeof(skip_buf))
483 			len = sizeof(skip_buf);
484 		wc_Arc4Process(&arc4, skip_buf, skip_buf, len);
485 		skip -= len;
486 	}
487 
488 	wc_Arc4Process(&arc4, data, data, data_len);
489 
490 	return 0;
491 #else /* NO_RC4 */
492 	return -1;
493 #endif /* NO_RC4 */
494 }
495 #endif /* CONFIG_NO_RC4 */
496 
497 
498 #if defined(EAP_IKEV2) || defined(EAP_IKEV2_DYNAMIC) \
499 		       || defined(EAP_SERVER_IKEV2)
500 union wolfssl_cipher {
501 	Aes aes;
502 	Des3 des3;
503 	Arc4 arc4;
504 };
505 
506 struct crypto_cipher {
507 	enum crypto_cipher_alg alg;
508 	union wolfssl_cipher enc;
509 	union wolfssl_cipher dec;
510 };
511 
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)512 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
513 					  const u8 *iv, const u8 *key,
514 					  size_t key_len)
515 {
516 	struct crypto_cipher *ctx;
517 
518 	ctx = os_zalloc(sizeof(*ctx));
519 	if (!ctx)
520 		return NULL;
521 
522 	switch (alg) {
523 #ifndef CONFIG_NO_RC4
524 #ifndef NO_RC4
525 	case CRYPTO_CIPHER_ALG_RC4:
526 		wc_Arc4SetKey(&ctx->enc.arc4, key, key_len);
527 		wc_Arc4SetKey(&ctx->dec.arc4, key, key_len);
528 		break;
529 #endif /* NO_RC4 */
530 #endif /* CONFIG_NO_RC4 */
531 #ifndef NO_AES
532 	case CRYPTO_CIPHER_ALG_AES:
533 		switch (key_len) {
534 		case 16:
535 		case 24:
536 		case 32:
537 			break;
538 		default:
539 			os_free(ctx);
540 			return NULL;
541 		}
542 		if (wc_AesSetKey(&ctx->enc.aes, key, key_len, iv,
543 				 AES_ENCRYPTION) ||
544 		    wc_AesSetKey(&ctx->dec.aes, key, key_len, iv,
545 				 AES_DECRYPTION)) {
546 			os_free(ctx);
547 			return NULL;
548 		}
549 		break;
550 #endif /* NO_AES */
551 #ifndef NO_DES3
552 	case CRYPTO_CIPHER_ALG_3DES:
553 		if (key_len != DES3_KEYLEN ||
554 		    wc_Des3_SetKey(&ctx->enc.des3, key, iv, DES_ENCRYPTION) ||
555 		    wc_Des3_SetKey(&ctx->dec.des3, key, iv, DES_DECRYPTION)) {
556 			os_free(ctx);
557 			return NULL;
558 		}
559 		break;
560 #endif /* NO_DES3 */
561 	case CRYPTO_CIPHER_ALG_RC2:
562 	case CRYPTO_CIPHER_ALG_DES:
563 	default:
564 		os_free(ctx);
565 		return NULL;
566 	}
567 
568 	ctx->alg = alg;
569 
570 	return ctx;
571 }
572 
573 
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)574 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
575 			  u8 *crypt, size_t len)
576 {
577 	switch (ctx->alg) {
578 #ifndef CONFIG_NO_RC4
579 #ifndef NO_RC4
580 	case CRYPTO_CIPHER_ALG_RC4:
581 		wc_Arc4Process(&ctx->enc.arc4, crypt, plain, len);
582 		return 0;
583 #endif /* NO_RC4 */
584 #endif /* CONFIG_NO_RC4 */
585 #ifndef NO_AES
586 	case CRYPTO_CIPHER_ALG_AES:
587 		if (wc_AesCbcEncrypt(&ctx->enc.aes, crypt, plain, len) != 0)
588 			return -1;
589 		return 0;
590 #endif /* NO_AES */
591 #ifndef NO_DES3
592 	case CRYPTO_CIPHER_ALG_3DES:
593 		if (wc_Des3_CbcEncrypt(&ctx->enc.des3, crypt, plain, len) != 0)
594 			return -1;
595 		return 0;
596 #endif /* NO_DES3 */
597 	default:
598 		return -1;
599 	}
600 	return -1;
601 }
602 
603 
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)604 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
605 			  u8 *plain, size_t len)
606 {
607 	switch (ctx->alg) {
608 #ifndef CONFIG_NO_RC4
609 #ifndef NO_RC4
610 	case CRYPTO_CIPHER_ALG_RC4:
611 		wc_Arc4Process(&ctx->dec.arc4, plain, crypt, len);
612 		return 0;
613 #endif /* NO_RC4 */
614 #endif /* CONFIG_NO_RC4 */
615 #ifndef NO_AES
616 	case CRYPTO_CIPHER_ALG_AES:
617 		if (wc_AesCbcDecrypt(&ctx->dec.aes, plain, crypt, len) != 0)
618 			return -1;
619 		return 0;
620 #endif /* NO_AES */
621 #ifndef NO_DES3
622 	case CRYPTO_CIPHER_ALG_3DES:
623 		if (wc_Des3_CbcDecrypt(&ctx->dec.des3, plain, crypt, len) != 0)
624 			return -1;
625 		return 0;
626 #endif /* NO_DES3 */
627 	default:
628 		return -1;
629 	}
630 	return -1;
631 }
632 
633 
crypto_cipher_deinit(struct crypto_cipher * ctx)634 void crypto_cipher_deinit(struct crypto_cipher *ctx)
635 {
636 	os_free(ctx);
637 }
638 
639 #endif
640 
641 
642 #ifdef CONFIG_WPS
643 
644 static const unsigned char RFC3526_PRIME_1536[] = {
645 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
646 	0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
647 	0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
648 	0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
649 	0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
650 	0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
651 	0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
652 	0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
653 	0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
654 	0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
655 	0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
656 	0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
657 	0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
658 	0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
659 	0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
660 	0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
661 };
662 
663 static const unsigned char RFC3526_GENERATOR_1536[] = {
664 	0x02
665 };
666 
667 #define RFC3526_LEN sizeof(RFC3526_PRIME_1536)
668 
669 
dh5_init(struct wpabuf ** priv,struct wpabuf ** publ)670 void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
671 {
672 	WC_RNG rng;
673 	DhKey *ret = NULL;
674 	DhKey *dh = NULL;
675 	struct wpabuf *privkey = NULL;
676 	struct wpabuf *pubkey = NULL;
677 	word32 priv_sz, pub_sz;
678 
679 	*priv = NULL;
680 	wpabuf_free(*publ);
681 	*publ = NULL;
682 
683 	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
684 	if (!dh)
685 		return NULL;
686 	wc_InitDhKey(dh);
687 
688 	if (wc_InitRng(&rng) != 0) {
689 		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
690 		return NULL;
691 	}
692 
693 	privkey = wpabuf_alloc(RFC3526_LEN);
694 	pubkey = wpabuf_alloc(RFC3526_LEN);
695 	if (!privkey || !pubkey)
696 		goto done;
697 
698 	if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
699 			RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
700 	    != 0)
701 		goto done;
702 
703 	priv_sz = pub_sz = RFC3526_LEN;
704 	if (wc_DhGenerateKeyPair(dh, &rng, wpabuf_mhead(privkey), &priv_sz,
705 				 wpabuf_mhead(pubkey), &pub_sz) != 0)
706 		goto done;
707 
708 	wpabuf_put(privkey, priv_sz);
709 	wpabuf_put(pubkey, pub_sz);
710 
711 	ret = dh;
712 	*priv = privkey;
713 	*publ = pubkey;
714 	dh = NULL;
715 	privkey = NULL;
716 	pubkey = NULL;
717 done:
718 	wpabuf_clear_free(pubkey);
719 	wpabuf_clear_free(privkey);
720 	if (dh) {
721 		wc_FreeDhKey(dh);
722 		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
723 	}
724 	wc_FreeRng(&rng);
725 	return ret;
726 }
727 
728 
729 #ifdef CONFIG_WPS_NFC
730 
dh5_init_fixed(const struct wpabuf * priv,const struct wpabuf * publ)731 void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
732 {
733 	DhKey *ret = NULL;
734 	DhKey *dh;
735 	byte *secret;
736 	word32 secret_sz;
737 
738 	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
739 	if (!dh)
740 		return NULL;
741 	wc_InitDhKey(dh);
742 
743 	secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
744 	if (!secret)
745 		goto done;
746 
747 	if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
748 			RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
749 	    != 0)
750 		goto done;
751 
752 	if (wc_DhAgree(dh, secret, &secret_sz, wpabuf_head(priv),
753 		       wpabuf_len(priv), RFC3526_GENERATOR_1536,
754 		       sizeof(RFC3526_GENERATOR_1536)) != 0)
755 		goto done;
756 
757 	if (secret_sz != wpabuf_len(publ) ||
758 	    os_memcmp(secret, wpabuf_head(publ), secret_sz) != 0)
759 		goto done;
760 
761 	ret = dh;
762 	dh = NULL;
763 done:
764 	if (dh) {
765 		wc_FreeDhKey(dh);
766 		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
767 	}
768 	XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
769 	return ret;
770 }
771 
772 #endif /* CONFIG_WPS_NFC */
773 
774 
dh5_derive_shared(void * ctx,const struct wpabuf * peer_public,const struct wpabuf * own_private)775 struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
776 				  const struct wpabuf *own_private)
777 {
778 	struct wpabuf *ret = NULL;
779 	struct wpabuf *secret;
780 	word32 secret_sz;
781 
782 	secret = wpabuf_alloc(RFC3526_LEN);
783 	if (!secret)
784 		goto done;
785 
786 	if (wc_DhAgree(ctx, wpabuf_mhead(secret), &secret_sz,
787 		       wpabuf_head(own_private), wpabuf_len(own_private),
788 		       wpabuf_head(peer_public), wpabuf_len(peer_public)) != 0)
789 		goto done;
790 
791 	wpabuf_put(secret, secret_sz);
792 
793 	ret = secret;
794 	secret = NULL;
795 done:
796 	wpabuf_clear_free(secret);
797 	return ret;
798 }
799 
800 
dh5_free(void * ctx)801 void dh5_free(void *ctx)
802 {
803 	if (!ctx)
804 		return;
805 
806 	wc_FreeDhKey(ctx);
807 	XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
808 }
809 
810 #endif /* CONFIG_WPS */
811 
812 
crypto_dh_init(u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)813 int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
814 		   u8 *pubkey)
815 {
816 	int ret = -1;
817 	WC_RNG rng;
818 	DhKey *dh = NULL;
819 	word32 priv_sz, pub_sz;
820 
821 	if (TEST_FAIL())
822 		return -1;
823 
824 	dh = os_malloc(sizeof(DhKey));
825 	if (!dh)
826 		return -1;
827 	wc_InitDhKey(dh);
828 
829 	if (wc_InitRng(&rng) != 0) {
830 		os_free(dh);
831 		return -1;
832 	}
833 
834 	if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
835 		goto done;
836 
837 	priv_sz = pub_sz = prime_len;
838 	if (wc_DhGenerateKeyPair(dh, &rng, privkey, &priv_sz, pubkey, &pub_sz)
839 	    != 0)
840 		goto done;
841 
842 	if (priv_sz < prime_len) {
843 		size_t pad_sz = prime_len - priv_sz;
844 
845 		os_memmove(privkey + pad_sz, privkey, priv_sz);
846 		os_memset(privkey, 0, pad_sz);
847 	}
848 
849 	if (pub_sz < prime_len) {
850 		size_t pad_sz = prime_len - pub_sz;
851 
852 		os_memmove(pubkey + pad_sz, pubkey, pub_sz);
853 		os_memset(pubkey, 0, pad_sz);
854 	}
855 	ret = 0;
856 done:
857 	wc_FreeDhKey(dh);
858 	os_free(dh);
859 	wc_FreeRng(&rng);
860 	return ret;
861 }
862 
863 
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)864 int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len,
865 			    const u8 *order, size_t order_len,
866 			    const u8 *privkey, size_t privkey_len,
867 			    const u8 *pubkey, size_t pubkey_len,
868 			    u8 *secret, size_t *len)
869 {
870 	int ret = -1;
871 	DhKey *dh;
872 	word32 secret_sz;
873 
874 	dh = os_malloc(sizeof(DhKey));
875 	if (!dh)
876 		return -1;
877 	wc_InitDhKey(dh);
878 
879 	if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
880 		goto done;
881 
882 	if (wc_DhAgree(dh, secret, &secret_sz, privkey, privkey_len, pubkey,
883 		       pubkey_len) != 0)
884 		goto done;
885 
886 	*len = secret_sz;
887 	ret = 0;
888 done:
889 	wc_FreeDhKey(dh);
890 	os_free(dh);
891 	return ret;
892 }
893 
894 
895 #ifdef CONFIG_FIPS
crypto_get_random(void * buf,size_t len)896 int crypto_get_random(void *buf, size_t len)
897 {
898 	int ret = 0;
899 	WC_RNG rng;
900 
901 	if (wc_InitRng(&rng) != 0)
902 		return -1;
903 	if (wc_RNG_GenerateBlock(&rng, buf, len) != 0)
904 		ret = -1;
905 	wc_FreeRng(&rng);
906 	return ret;
907 }
908 #endif /* CONFIG_FIPS */
909 
910 
911 #if defined(EAP_PWD) || defined(EAP_SERVER_PWD)
912 struct crypto_hash {
913 	Hmac hmac;
914 	int size;
915 };
916 
917 
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)918 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
919 				      size_t key_len)
920 {
921 	struct crypto_hash *ret = NULL;
922 	struct crypto_hash *hash;
923 	int type;
924 
925 	hash = os_zalloc(sizeof(*hash));
926 	if (!hash)
927 		goto done;
928 
929 	switch (alg) {
930 #ifndef NO_MD5
931 	case CRYPTO_HASH_ALG_HMAC_MD5:
932 		hash->size = 16;
933 		type = WC_MD5;
934 		break;
935 #endif /* NO_MD5 */
936 #ifndef NO_SHA
937 	case CRYPTO_HASH_ALG_HMAC_SHA1:
938 		type = WC_SHA;
939 		hash->size = 20;
940 		break;
941 #endif /* NO_SHA */
942 #ifdef CONFIG_SHA256
943 #ifndef NO_SHA256
944 	case CRYPTO_HASH_ALG_HMAC_SHA256:
945 		type = WC_SHA256;
946 		hash->size = 32;
947 		break;
948 #endif /* NO_SHA256 */
949 #endif /* CONFIG_SHA256 */
950 	default:
951 		goto done;
952 	}
953 
954 	if (wc_HmacInit(&hash->hmac, NULL, INVALID_DEVID) != 0 ||
955 	    wc_HmacSetKey(&hash->hmac, type, key, key_len) != 0)
956 		goto done;
957 
958 	ret = hash;
959 	hash = NULL;
960 done:
961 	os_free(hash);
962 	return ret;
963 }
964 
965 
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)966 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
967 {
968 	if (!ctx)
969 		return;
970 	wc_HmacUpdate(&ctx->hmac, data, len);
971 }
972 
973 
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)974 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
975 {
976 	int ret = 0;
977 
978 	if (!ctx)
979 		return -2;
980 
981 	if (!mac || !len)
982 		goto done;
983 
984 	if (wc_HmacFinal(&ctx->hmac, mac) != 0) {
985 		ret = -1;
986 		goto done;
987 	}
988 
989 	*len = ctx->size;
990 	ret = 0;
991 done:
992 	bin_clear_free(ctx, sizeof(*ctx));
993 	if (TEST_FAIL())
994 		return -1;
995 	return ret;
996 }
997 
998 #endif
999 
1000 
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1001 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
1002 		     const u8 *addr[], const size_t *len, u8 *mac)
1003 {
1004 	Cmac cmac;
1005 	size_t i;
1006 	word32 sz;
1007 
1008 	if (TEST_FAIL())
1009 		return -1;
1010 
1011 	if (wc_InitCmac(&cmac, key, key_len, WC_CMAC_AES, NULL) != 0)
1012 		return -1;
1013 
1014 	for (i = 0; i < num_elem; i++)
1015 		if (wc_CmacUpdate(&cmac, addr[i], len[i]) != 0)
1016 			return -1;
1017 
1018 	sz = AES_BLOCK_SIZE;
1019 	if (wc_CmacFinal(&cmac, mac, &sz) != 0 || sz != AES_BLOCK_SIZE)
1020 		return -1;
1021 
1022 	return 0;
1023 }
1024 
1025 
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1026 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1027 			 const u8 *addr[], const size_t *len, u8 *mac)
1028 {
1029 	return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1030 }
1031 
1032 
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1033 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1034 {
1035 	return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1036 }
1037 
1038 
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1039 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1040 {
1041 	return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1042 }
1043 
1044 
crypto_bignum_init(void)1045 struct crypto_bignum * crypto_bignum_init(void)
1046 {
1047 	mp_int *a;
1048 
1049 	if (TEST_FAIL())
1050 		return NULL;
1051 
1052 	a = os_malloc(sizeof(*a));
1053 	if (!a || mp_init(a) != MP_OKAY) {
1054 		os_free(a);
1055 		a = NULL;
1056 	}
1057 
1058 	return (struct crypto_bignum *) a;
1059 }
1060 
1061 
crypto_bignum_init_set(const u8 * buf,size_t len)1062 struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
1063 {
1064 	mp_int *a;
1065 
1066 	if (TEST_FAIL())
1067 		return NULL;
1068 
1069 	a = (mp_int *) crypto_bignum_init();
1070 	if (!a)
1071 		return NULL;
1072 
1073 	if (mp_read_unsigned_bin(a, buf, len) != MP_OKAY) {
1074 		os_free(a);
1075 		a = NULL;
1076 	}
1077 
1078 	return (struct crypto_bignum *) a;
1079 }
1080 
1081 
crypto_bignum_init_uint(unsigned int val)1082 struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
1083 {
1084 	mp_int *a;
1085 
1086 	if (TEST_FAIL())
1087 		return NULL;
1088 
1089 	a = (mp_int *) crypto_bignum_init();
1090 	if (!a)
1091 		return NULL;
1092 
1093 	if (mp_set_int(a, val) != MP_OKAY) {
1094 		os_free(a);
1095 		a = NULL;
1096 	}
1097 
1098 	return (struct crypto_bignum *) a;
1099 }
1100 
1101 
crypto_bignum_deinit(struct crypto_bignum * n,int clear)1102 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1103 {
1104 	if (!n)
1105 		return;
1106 
1107 	if (clear)
1108 		mp_forcezero((mp_int *) n);
1109 	mp_clear((mp_int *) n);
1110 	os_free((mp_int *) n);
1111 }
1112 
1113 
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)1114 int crypto_bignum_to_bin(const struct crypto_bignum *a,
1115 			 u8 *buf, size_t buflen, size_t padlen)
1116 {
1117 	int num_bytes, offset;
1118 
1119 	if (TEST_FAIL())
1120 		return -1;
1121 
1122 	if (padlen > buflen)
1123 		return -1;
1124 
1125 	num_bytes = (mp_count_bits((mp_int *) a) + 7) / 8;
1126 	if ((size_t) num_bytes > buflen)
1127 		return -1;
1128 	if (padlen > (size_t) num_bytes)
1129 		offset = padlen - num_bytes;
1130 	else
1131 		offset = 0;
1132 
1133 	os_memset(buf, 0, offset);
1134 	mp_to_unsigned_bin((mp_int *) a, buf + offset);
1135 
1136 	return num_bytes + offset;
1137 }
1138 
1139 
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)1140 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
1141 {
1142 	int ret = 0;
1143 	WC_RNG rng;
1144 	size_t len;
1145 	u8 *buf;
1146 
1147 	if (TEST_FAIL())
1148 		return -1;
1149 	if (wc_InitRng(&rng) != 0)
1150 		return -1;
1151 	len = (mp_count_bits((mp_int *) m) + 7) / 8;
1152 	buf = os_malloc(len);
1153 	if (!buf || wc_RNG_GenerateBlock(&rng, buf, len) != 0 ||
1154 	    mp_read_unsigned_bin((mp_int *) r, buf, len) != MP_OKAY ||
1155 	    mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0)
1156 		ret = -1;
1157 	wc_FreeRng(&rng);
1158 	bin_clear_free(buf, len);
1159 	return ret;
1160 }
1161 
1162 
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)1163 int crypto_bignum_add(const struct crypto_bignum *a,
1164 		      const struct crypto_bignum *b,
1165 		      struct crypto_bignum *r)
1166 {
1167 	return mp_add((mp_int *) a, (mp_int *) b,
1168 		      (mp_int *) r) == MP_OKAY ? 0 : -1;
1169 }
1170 
1171 
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)1172 int crypto_bignum_mod(const struct crypto_bignum *a,
1173 		      const struct crypto_bignum *m,
1174 		      struct crypto_bignum *r)
1175 {
1176 	return mp_mod((mp_int *) a, (mp_int *) m,
1177 		      (mp_int *) r) == MP_OKAY ? 0 : -1;
1178 }
1179 
1180 
crypto_bignum_exptmod(const struct crypto_bignum * b,const struct crypto_bignum * e,const struct crypto_bignum * m,struct crypto_bignum * r)1181 int crypto_bignum_exptmod(const struct crypto_bignum *b,
1182 			  const struct crypto_bignum *e,
1183 			  const struct crypto_bignum *m,
1184 			  struct crypto_bignum *r)
1185 {
1186 	if (TEST_FAIL())
1187 		return -1;
1188 
1189 	return mp_exptmod((mp_int *) b, (mp_int *) e, (mp_int *) m,
1190 			  (mp_int *) r) == MP_OKAY ?  0 : -1;
1191 }
1192 
1193 
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)1194 int crypto_bignum_inverse(const struct crypto_bignum *a,
1195 			  const struct crypto_bignum *m,
1196 			  struct crypto_bignum *r)
1197 {
1198 	if (TEST_FAIL())
1199 		return -1;
1200 
1201 	return mp_invmod((mp_int *) a, (mp_int *) m,
1202 			 (mp_int *) r) == MP_OKAY ? 0 : -1;
1203 }
1204 
1205 
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)1206 int crypto_bignum_sub(const struct crypto_bignum *a,
1207 		      const struct crypto_bignum *b,
1208 		      struct crypto_bignum *r)
1209 {
1210 	if (TEST_FAIL())
1211 		return -1;
1212 
1213 	return mp_sub((mp_int *) a, (mp_int *) b,
1214 		      (mp_int *) r) == MP_OKAY ? 0 : -1;
1215 }
1216 
1217 
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * d)1218 int crypto_bignum_div(const struct crypto_bignum *a,
1219 		      const struct crypto_bignum *b,
1220 		      struct crypto_bignum *d)
1221 {
1222 	if (TEST_FAIL())
1223 		return -1;
1224 
1225 	return mp_div((mp_int *) a, (mp_int *) b, (mp_int *) d,
1226 		      NULL) == MP_OKAY ? 0 : -1;
1227 }
1228 
1229 
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)1230 int crypto_bignum_addmod(const struct crypto_bignum *a,
1231 			 const struct crypto_bignum *b,
1232 			 const struct crypto_bignum *c,
1233 			 struct crypto_bignum *d)
1234 {
1235 	if (TEST_FAIL())
1236 		return -1;
1237 
1238 	return mp_addmod((mp_int *) a, (mp_int *) b, (mp_int *) c,
1239 			 (mp_int *) d) == MP_OKAY ?  0 : -1;
1240 }
1241 
1242 
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * m,struct crypto_bignum * d)1243 int crypto_bignum_mulmod(const struct crypto_bignum *a,
1244 			 const struct crypto_bignum *b,
1245 			 const struct crypto_bignum *m,
1246 			 struct crypto_bignum *d)
1247 {
1248 	if (TEST_FAIL())
1249 		return -1;
1250 
1251 	return mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) m,
1252 			 (mp_int *) d) == MP_OKAY ?  0 : -1;
1253 }
1254 
1255 
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1256 int crypto_bignum_sqrmod(const struct crypto_bignum *a,
1257 			 const struct crypto_bignum *b,
1258 			 struct crypto_bignum *c)
1259 {
1260 	if (TEST_FAIL())
1261 		return -1;
1262 
1263 	return mp_sqrmod((mp_int *) a, (mp_int *) b,
1264 			 (mp_int *) c) == MP_OKAY ?  0 : -1;
1265 }
1266 
1267 
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)1268 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1269 			 struct crypto_bignum *r)
1270 {
1271 	if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1272 		return -1;
1273 	mp_rshb((mp_int *) r, n);
1274 	return 0;
1275 }
1276 
1277 
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)1278 int crypto_bignum_cmp(const struct crypto_bignum *a,
1279 		      const struct crypto_bignum *b)
1280 {
1281 	return mp_cmp((mp_int *) a, (mp_int *) b);
1282 }
1283 
1284 
crypto_bignum_is_zero(const struct crypto_bignum * a)1285 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1286 {
1287 	return mp_iszero((mp_int *) a);
1288 }
1289 
1290 
crypto_bignum_is_one(const struct crypto_bignum * a)1291 int crypto_bignum_is_one(const struct crypto_bignum *a)
1292 {
1293 	return mp_isone((const mp_int *) a);
1294 }
1295 
crypto_bignum_is_odd(const struct crypto_bignum * a)1296 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1297 {
1298 	return mp_isodd((mp_int *) a);
1299 }
1300 
1301 
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)1302 int crypto_bignum_legendre(const struct crypto_bignum *a,
1303 			   const struct crypto_bignum *p)
1304 {
1305 	mp_int t;
1306 	int ret;
1307 	int res = -2;
1308 
1309 	if (TEST_FAIL())
1310 		return -2;
1311 
1312 	if (mp_init(&t) != MP_OKAY)
1313 		return -2;
1314 
1315 	/* t = (p-1) / 2 */
1316 	ret = mp_sub_d((mp_int *) p, 1, &t);
1317 	if (ret == MP_OKAY)
1318 		mp_rshb(&t, 1);
1319 	if (ret == MP_OKAY)
1320 		ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1321 	if (ret == MP_OKAY) {
1322 		if (mp_isone(&t))
1323 			res = 1;
1324 		else if (mp_iszero(&t))
1325 			res = 0;
1326 		else
1327 			res = -1;
1328 	}
1329 
1330 	mp_clear(&t);
1331 	return res;
1332 }
1333 
1334 
1335 #ifdef CONFIG_ECC
1336 
1337 int ecc_map(ecc_point *, mp_int *, mp_digit);
1338 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1339 			     mp_int *a, mp_int *modulus, mp_digit mp);
1340 
1341 struct crypto_ec {
1342 	ecc_key key;
1343 	mp_int a;
1344 	mp_int prime;
1345 	mp_int order;
1346 	mp_digit mont_b;
1347 	mp_int b;
1348 };
1349 
1350 
crypto_ec_init(int group)1351 struct crypto_ec * crypto_ec_init(int group)
1352 {
1353 	int built = 0;
1354 	struct crypto_ec *e;
1355 	int curve_id;
1356 
1357 	/* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1358 	switch (group) {
1359 	case 19:
1360 		curve_id = ECC_SECP256R1;
1361 		break;
1362 	case 20:
1363 		curve_id = ECC_SECP384R1;
1364 		break;
1365 	case 21:
1366 		curve_id = ECC_SECP521R1;
1367 		break;
1368 	case 25:
1369 		curve_id = ECC_SECP192R1;
1370 		break;
1371 	case 26:
1372 		curve_id = ECC_SECP224R1;
1373 		break;
1374 #ifdef HAVE_ECC_BRAINPOOL
1375 	case 27:
1376 		curve_id = ECC_BRAINPOOLP224R1;
1377 		break;
1378 	case 28:
1379 		curve_id = ECC_BRAINPOOLP256R1;
1380 		break;
1381 	case 29:
1382 		curve_id = ECC_BRAINPOOLP384R1;
1383 		break;
1384 	case 30:
1385 		curve_id = ECC_BRAINPOOLP512R1;
1386 		break;
1387 #endif /* HAVE_ECC_BRAINPOOL */
1388 	default:
1389 		return NULL;
1390 	}
1391 
1392 	e = os_zalloc(sizeof(*e));
1393 	if (!e)
1394 		return NULL;
1395 
1396 	if (wc_ecc_init(&e->key) != 0 ||
1397 	    wc_ecc_set_curve(&e->key, 0, curve_id) != 0 ||
1398 	    mp_init(&e->a) != MP_OKAY ||
1399 	    mp_init(&e->prime) != MP_OKAY ||
1400 	    mp_init(&e->order) != MP_OKAY ||
1401 	    mp_init(&e->b) != MP_OKAY ||
1402 	    mp_read_radix(&e->a, e->key.dp->Af, 16) != MP_OKAY ||
1403 	    mp_read_radix(&e->b, e->key.dp->Bf, 16) != MP_OKAY ||
1404 	    mp_read_radix(&e->prime, e->key.dp->prime, 16) != MP_OKAY ||
1405 	    mp_read_radix(&e->order, e->key.dp->order, 16) != MP_OKAY ||
1406 	    mp_montgomery_setup(&e->prime, &e->mont_b) != MP_OKAY)
1407 		goto done;
1408 
1409 	built = 1;
1410 done:
1411 	if (!built) {
1412 		crypto_ec_deinit(e);
1413 		e = NULL;
1414 	}
1415 	return e;
1416 }
1417 
1418 
crypto_ec_deinit(struct crypto_ec * e)1419 void crypto_ec_deinit(struct crypto_ec* e)
1420 {
1421 	if (!e)
1422 		return;
1423 
1424 	mp_clear(&e->b);
1425 	mp_clear(&e->order);
1426 	mp_clear(&e->prime);
1427 	mp_clear(&e->a);
1428 	wc_ecc_free(&e->key);
1429 	os_free(e);
1430 }
1431 
1432 
crypto_ec_point_init(struct crypto_ec * e)1433 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1434 {
1435 	if (TEST_FAIL())
1436 		return NULL;
1437 	if (!e)
1438 		return NULL;
1439 	return (struct crypto_ec_point *) wc_ecc_new_point();
1440 }
1441 
1442 
crypto_ec_prime_len(struct crypto_ec * e)1443 size_t crypto_ec_prime_len(struct crypto_ec *e)
1444 {
1445 	return (mp_count_bits(&e->prime) + 7) / 8;
1446 }
1447 
1448 
crypto_ec_prime_len_bits(struct crypto_ec * e)1449 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1450 {
1451 	return mp_count_bits(&e->prime);
1452 }
1453 
1454 
crypto_ec_order_len(struct crypto_ec * e)1455 size_t crypto_ec_order_len(struct crypto_ec *e)
1456 {
1457 	return (mp_count_bits(&e->order) + 7) / 8;
1458 }
1459 
1460 
crypto_ec_get_prime(struct crypto_ec * e)1461 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1462 {
1463 	return (const struct crypto_bignum *) &e->prime;
1464 }
1465 
1466 
crypto_ec_get_order(struct crypto_ec * e)1467 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1468 {
1469 	return (const struct crypto_bignum *) &e->order;
1470 }
1471 
1472 
crypto_ec_get_a(struct crypto_ec * e)1473 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1474 {
1475 	return (const struct crypto_bignum *) &e->a;
1476 }
1477 
1478 
crypto_ec_get_b(struct crypto_ec * e)1479 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1480 {
1481 	return (const struct crypto_bignum *) &e->b;
1482 }
1483 
1484 
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)1485 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1486 {
1487 	ecc_point *point = (ecc_point *) p;
1488 
1489 	if (!p)
1490 		return;
1491 
1492 	if (clear) {
1493 		mp_forcezero(point->x);
1494 		mp_forcezero(point->y);
1495 		mp_forcezero(point->z);
1496 	}
1497 	wc_ecc_del_point(point);
1498 }
1499 
1500 
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)1501 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1502 		      struct crypto_bignum *x)
1503 {
1504 	return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1505 }
1506 
1507 
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)1508 int crypto_ec_point_to_bin(struct crypto_ec *e,
1509 			   const struct crypto_ec_point *point, u8 *x, u8 *y)
1510 {
1511 	ecc_point *p = (ecc_point *) point;
1512 
1513 	if (TEST_FAIL())
1514 		return -1;
1515 
1516 	if (!mp_isone(p->z)) {
1517 		if (ecc_map(p, &e->prime, e->mont_b) != MP_OKAY)
1518 			return -1;
1519 	}
1520 
1521 	if (x) {
1522 		if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1523 					 e->key.dp->size,
1524 					 e->key.dp->size) <= 0)
1525 			return -1;
1526 	}
1527 
1528 	if (y) {
1529 		if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1530 					 e->key.dp->size,
1531 					 e->key.dp->size) <= 0)
1532 			return -1;
1533 	}
1534 
1535 	return 0;
1536 }
1537 
1538 
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)1539 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1540 						  const u8 *val)
1541 {
1542 	ecc_point *point = NULL;
1543 	int loaded = 0;
1544 
1545 	if (TEST_FAIL())
1546 		return NULL;
1547 
1548 	point = wc_ecc_new_point();
1549 	if (!point)
1550 		goto done;
1551 
1552 	if (mp_read_unsigned_bin(point->x, val, e->key.dp->size) != MP_OKAY)
1553 		goto done;
1554 	val += e->key.dp->size;
1555 	if (mp_read_unsigned_bin(point->y, val, e->key.dp->size) != MP_OKAY)
1556 		goto done;
1557 	mp_set(point->z, 1);
1558 
1559 	loaded = 1;
1560 done:
1561 	if (!loaded) {
1562 		wc_ecc_del_point(point);
1563 		point = NULL;
1564 	}
1565 	return (struct crypto_ec_point *) point;
1566 }
1567 
1568 
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)1569 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1570 			const struct crypto_ec_point *b,
1571 			struct crypto_ec_point *c)
1572 {
1573 	mp_int mu;
1574 	ecc_point *ta = NULL, *tb = NULL;
1575 	ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1576 	mp_int *modulus = &e->prime;
1577 	int ret;
1578 
1579 	if (TEST_FAIL())
1580 		return -1;
1581 
1582 	ret = mp_init(&mu);
1583 	if (ret != MP_OKAY)
1584 		return -1;
1585 
1586 	ret = mp_montgomery_calc_normalization(&mu, modulus);
1587 	if (ret != MP_OKAY) {
1588 		mp_clear(&mu);
1589 		return -1;
1590 	}
1591 
1592 	if (!mp_isone(&mu)) {
1593 		ta = wc_ecc_new_point();
1594 		if (!ta) {
1595 			mp_clear(&mu);
1596 			return -1;
1597 		}
1598 		tb = wc_ecc_new_point();
1599 		if (!tb) {
1600 			wc_ecc_del_point(ta);
1601 			mp_clear(&mu);
1602 			return -1;
1603 		}
1604 
1605 		if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1606 		    mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1607 		    mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1608 		    mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1609 		    mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1610 		    mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1611 			ret = -1;
1612 			goto end;
1613 		}
1614 		pa = ta;
1615 		pb = tb;
1616 	}
1617 
1618 	ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1619 				       &e->prime, e->mont_b);
1620 	if (ret != 0) {
1621 		ret = -1;
1622 		goto end;
1623 	}
1624 
1625 	if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1626 		ret = -1;
1627 	else
1628 		ret = 0;
1629 end:
1630 	wc_ecc_del_point(tb);
1631 	wc_ecc_del_point(ta);
1632 	mp_clear(&mu);
1633 	return ret;
1634 }
1635 
1636 
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)1637 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1638 			const struct crypto_bignum *b,
1639 			struct crypto_ec_point *res)
1640 {
1641 	int ret;
1642 
1643 	if (TEST_FAIL())
1644 		return -1;
1645 
1646 	ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
1647 			    &e->a, &e->prime, 1);
1648 	return ret == 0 ? 0 : -1;
1649 }
1650 
1651 
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)1652 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1653 {
1654 	ecc_point *point = (ecc_point *) p;
1655 
1656 	if (TEST_FAIL())
1657 		return -1;
1658 
1659 	if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
1660 		return -1;
1661 
1662 	return 0;
1663 }
1664 
1665 
1666 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)1667 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1668 			      const struct crypto_bignum *x)
1669 {
1670 	mp_int *y2;
1671 
1672 	if (TEST_FAIL())
1673 		return NULL;
1674 
1675 	/* y^2 = x^3 + ax + b = (x^2 + a)x + b */
1676 	y2 = (mp_int *) crypto_bignum_init();
1677 	if (!y2 ||
1678 	    mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
1679 	    mp_addmod(y2, &e->a, &e->prime, y2) != 0 ||
1680 	    mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
1681 	    mp_addmod(y2, &e->b, &e->prime, y2) != 0) {
1682 		mp_clear(y2);
1683 		os_free(y2);
1684 		y2 = NULL;
1685 	}
1686 
1687 	return (struct crypto_bignum *) y2;
1688 }
1689 
1690 
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)1691 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1692 				   const struct crypto_ec_point *p)
1693 {
1694 	return wc_ecc_point_is_at_infinity((ecc_point *) p);
1695 }
1696 
1697 
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)1698 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1699 				const struct crypto_ec_point *p)
1700 {
1701 	return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
1702 		MP_OKAY;
1703 }
1704 
1705 
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)1706 int crypto_ec_point_cmp(const struct crypto_ec *e,
1707 			const struct crypto_ec_point *a,
1708 			const struct crypto_ec_point *b)
1709 {
1710 	return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
1711 }
1712 
1713 
1714 struct crypto_ecdh {
1715 	struct crypto_ec *ec;
1716 	WC_RNG rng;
1717 };
1718 
crypto_ecdh_init(int group)1719 struct crypto_ecdh * crypto_ecdh_init(int group)
1720 {
1721 	struct crypto_ecdh *ecdh = NULL;
1722 	int ret;
1723 
1724 	ecdh = os_zalloc(sizeof(*ecdh));
1725 	if (!ecdh)
1726 		goto fail;
1727 
1728 	if (wc_InitRng(&ecdh->rng) != 0)
1729 		goto fail;
1730 
1731 	ecdh->ec = crypto_ec_init(group);
1732 	if (!ecdh->ec)
1733 		goto fail;
1734 
1735 	ret = wc_ecc_make_key_ex(&ecdh->rng, ecdh->ec->key.dp->size,
1736 				 &ecdh->ec->key, ecdh->ec->key.dp->id);
1737 	if (ret < 0)
1738 		goto fail;
1739 
1740 #if defined(ECC_TIMING_RESISTANT) && !defined(CONFIG_FIPS)
1741 	ret = wc_ecc_set_rng(&ecdh->ec->key, &ecdh->rng);
1742 	if (ret < 0)
1743 		goto fail;
1744 #endif /* ECC_TIMING_RESISTANT && !CONFIG_FIPS */
1745 
1746 done:
1747 	return ecdh;
1748 fail:
1749 	crypto_ecdh_deinit(ecdh);
1750 	ecdh = NULL;
1751 	goto done;
1752 }
1753 
1754 
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)1755 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
1756 {
1757 	if (ecdh) {
1758 		crypto_ec_deinit(ecdh->ec);
1759 		wc_FreeRng(&ecdh->rng);
1760 		os_free(ecdh);
1761 	}
1762 }
1763 
1764 
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)1765 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
1766 {
1767 	struct wpabuf *buf = NULL;
1768 	int ret;
1769 	int len = ecdh->ec->key.dp->size;
1770 
1771 	buf = wpabuf_alloc(inc_y ? 2 * len : len);
1772 	if (!buf)
1773 		goto fail;
1774 
1775 	ret = crypto_bignum_to_bin((struct crypto_bignum *)
1776 				   ecdh->ec->key.pubkey.x, wpabuf_put(buf, len),
1777 				   len, len);
1778 	if (ret < 0)
1779 		goto fail;
1780 	if (inc_y) {
1781 		ret = crypto_bignum_to_bin((struct crypto_bignum *)
1782 					   ecdh->ec->key.pubkey.y,
1783 					   wpabuf_put(buf, len), len, len);
1784 		if (ret < 0)
1785 			goto fail;
1786 	}
1787 
1788 done:
1789 	return buf;
1790 fail:
1791 	wpabuf_free(buf);
1792 	buf = NULL;
1793 	goto done;
1794 }
1795 
1796 
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)1797 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
1798 					const u8 *key, size_t len)
1799 {
1800 	int ret;
1801 	struct wpabuf *pubkey = NULL;
1802 	struct wpabuf *secret = NULL;
1803 	word32 key_len = ecdh->ec->key.dp->size;
1804 	ecc_point *point = NULL;
1805 	size_t need_key_len = inc_y ? 2 * key_len : key_len;
1806 
1807 	if (len < need_key_len)
1808 		goto fail;
1809 	pubkey = wpabuf_alloc(1 + 2 * key_len);
1810 	if (!pubkey)
1811 		goto fail;
1812 	wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
1813 	wpabuf_put_data(pubkey, key, need_key_len);
1814 
1815 	point = wc_ecc_new_point();
1816 	if (!point)
1817 		goto fail;
1818 
1819 	ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
1820 				      ecdh->ec->key.idx, point);
1821 	if (ret != MP_OKAY)
1822 		goto fail;
1823 
1824 	secret = wpabuf_alloc(key_len);
1825 	if (!secret)
1826 		goto fail;
1827 
1828 	ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point,
1829 				      wpabuf_put(secret, key_len), &key_len);
1830 	if (ret != MP_OKAY)
1831 		goto fail;
1832 
1833 done:
1834 	wc_ecc_del_point(point);
1835 	wpabuf_free(pubkey);
1836 	return secret;
1837 fail:
1838 	wpabuf_free(secret);
1839 	secret = NULL;
1840 	goto done;
1841 }
1842 
1843 
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)1844 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
1845 {
1846 	return crypto_ec_prime_len(ecdh->ec);
1847 }
1848 
1849 
1850 struct crypto_ec_key {
1851 	ecc_key *eckey;
1852 	WC_RNG *rng; /* Needs to be initialized before use.
1853 		      * *NOT* initialized in crypto_ec_key_init */
1854 };
1855 
1856 
crypto_ec_key_init(void)1857 static struct crypto_ec_key * crypto_ec_key_init(void)
1858 {
1859 	struct crypto_ec_key *key;
1860 
1861 	key = os_zalloc(sizeof(struct crypto_ec_key));
1862 	if (key) {
1863 #ifdef CONFIG_FIPS
1864 		key->eckey = os_zalloc(sizeof(ecc_key));
1865 #else /* CONFIG_FIPS */
1866 		key->eckey = wc_ecc_key_new(NULL);
1867 #endif /* CONFIG_FIPS */
1868 		/* Omit key->rng initialization because it seeds itself and thus
1869 		 * consumes entropy that may never be used. Lazy initialize when
1870 		 * necessary. */
1871 		if (!key->eckey) {
1872 			wpa_printf(MSG_ERROR,
1873 				   "wolfSSL: crypto_ec_key_init() failed");
1874 			crypto_ec_key_deinit(key);
1875 			key = NULL;
1876 		}
1877 #ifdef CONFIG_FIPS
1878 		else if (wc_ecc_init_ex(key->eckey, NULL, INVALID_DEVID) != 0) {
1879 			wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_init_ex failed");
1880 			crypto_ec_key_deinit(key);
1881 			key = NULL;
1882 		}
1883 #endif /* CONFIG_FIPS */
1884 	}
1885 	return key;
1886 }
1887 
1888 
crypto_ec_key_deinit(struct crypto_ec_key * key)1889 void crypto_ec_key_deinit(struct crypto_ec_key *key)
1890 {
1891 	if (key) {
1892 #ifdef CONFIG_FIPS
1893 		os_free(key->rng);
1894 		os_free(key->eckey);
1895 #else /* CONFIG_FIPS */
1896 		wc_rng_free(key->rng);
1897 		wc_ecc_key_free(key->eckey);
1898 #endif /* CONFIG_FIPS */
1899 		os_free(key);
1900 	}
1901 }
1902 
1903 
crypto_ec_key_parse_priv(const u8 * der,size_t der_len)1904 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
1905 {
1906 	struct crypto_ec_key *ret;
1907 	word32 idx = 0;
1908 
1909 	ret = crypto_ec_key_init();
1910 	if (!ret) {
1911 		wpa_printf(MSG_ERROR, "wolfSSL: crypto_ec_key_init failed");
1912 		goto fail;
1913 	}
1914 
1915 	if (wc_EccPrivateKeyDecode(der, &idx, ret->eckey, (word32) der_len) !=
1916 	    0) {
1917 		wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPrivateKeyDecode failed");
1918 		goto fail;
1919 	}
1920 
1921 	return ret;
1922 fail:
1923 	if (ret)
1924 		crypto_ec_key_deinit(ret);
1925 	return NULL;
1926 }
1927 
1928 
crypto_ec_key_group(struct crypto_ec_key * key)1929 int crypto_ec_key_group(struct crypto_ec_key *key)
1930 {
1931 
1932 	if (!key || !key->eckey || !key->eckey->dp) {
1933 		wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
1934 			   __func__);
1935 		return -1;
1936 	}
1937 
1938 	switch (key->eckey->dp->id) {
1939 	case ECC_SECP256R1:
1940 		return 19;
1941 	case ECC_SECP384R1:
1942 		return 20;
1943 	case ECC_SECP521R1:
1944 		return 21;
1945 	case ECC_BRAINPOOLP256R1:
1946 		return 28;
1947 	case ECC_BRAINPOOLP384R1:
1948 		return 29;
1949 	case ECC_BRAINPOOLP512R1:
1950 		return 30;
1951 	}
1952 
1953 	wpa_printf(MSG_ERROR, "wolfSSL: Unsupported curve (id=%d) in EC key",
1954 		   key->eckey->dp->id);
1955 	return -1;
1956 }
1957 
1958 
crypto_ec_key_get_subject_public_key(struct crypto_ec_key * key)1959 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
1960 {
1961 	byte *der = NULL;
1962 	int der_len;
1963 	struct wpabuf *ret = NULL;
1964 
1965 	if (!key || !key->eckey) {
1966 		wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
1967 			   __func__);
1968 		goto fail;
1969 	}
1970 
1971 	der_len = wc_EccPublicKeyDerSize(key->eckey, 1);
1972 	if (der_len <= 0) {
1973 		wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyDerSize failed");
1974 		goto fail;
1975 	}
1976 
1977 	der = os_malloc(der_len);
1978 	if (!der)
1979 		goto fail;
1980 
1981 	der_len = wc_EccPublicKeyToDer(key->eckey, der, der_len, 1);
1982 	if (der_len <= 0) {
1983 		wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyToDer failed");
1984 		goto fail;
1985 	}
1986 
1987 	ret = wpabuf_alloc_copy(der, der_len);
1988 	os_free(der);
1989 	return ret;
1990 
1991 fail:
1992 	os_free(der);
1993 	return NULL;
1994 }
1995 
1996 
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)1997 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
1998 {
1999 	word32 idx = 0;
2000 	struct crypto_ec_key *ret = NULL;
2001 
2002 	ret = crypto_ec_key_init();
2003 	if (!ret) {
2004 		wpa_printf(MSG_ERROR, "wolfSSL: crypto_ec_key_init failed");
2005 		goto fail;
2006 	}
2007 
2008 	if (wc_EccPublicKeyDecode(der, &idx, ret->eckey, (word32) der_len) != 0)
2009 	{
2010 		wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyDecode failed");
2011 		goto fail;
2012 	}
2013 
2014 	return ret;
2015 fail:
2016 	crypto_ec_key_deinit(ret);
2017 	return NULL;
2018 }
2019 
2020 
crypto_ec_key_sign(struct crypto_ec_key * key,const u8 * data,size_t len)2021 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
2022 				   size_t len)
2023 {
2024 	byte *der = NULL;
2025 	int der_len;
2026 	word32 w32_der_len;
2027 	struct wpabuf *ret = NULL;
2028 
2029 	if (!key || !key->eckey || !data || len == 0) {
2030 		wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
2031 			   __func__);
2032 		goto fail;
2033 	}
2034 
2035 	if (!key->rng) {
2036 		/* Lazy init key->rng */
2037 #ifdef CONFIG_FIPS
2038 		key->rng = os_zalloc(sizeof(WC_RNG));
2039 #else /* CONFIG_FIPS */
2040 		key->rng = wc_rng_new(NULL, 0, NULL);
2041 #endif /* CONFIG_FIPS */
2042 		if (!key->rng) {
2043 			wpa_printf(MSG_ERROR, "wolfSSL: wc_rng_new failed");
2044 			goto fail;
2045 		}
2046 #ifdef CONFIG_FIPS
2047 		if (wc_InitRng(key->rng) != 0) {
2048 			wpa_printf(MSG_ERROR, "wolfSSL: wc_InitRng failed");
2049 			goto fail;
2050 		}
2051 #endif /* CONFIG_FIPS */
2052 	}
2053 
2054 	der_len = wc_ecc_sig_size(key->eckey);
2055 	if (der_len <= 0) {
2056 		wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_sig_size failed");
2057 		goto fail;
2058 	}
2059 
2060 	der = os_malloc(der_len);
2061 	if (!der)
2062 		goto fail;
2063 
2064 	w32_der_len = (word32) der_len;
2065 	if (wc_ecc_sign_hash(data, len, der, &w32_der_len, key->rng, key->eckey)
2066 	    != 0) {
2067 		wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_sign_hash failed");
2068 		goto fail;
2069 	}
2070 
2071 	ret = wpabuf_alloc_copy(der, der_len);
2072 	os_free(der);
2073 	if (!ret)
2074 		wpa_printf(MSG_ERROR, "wolfSSL: wpabuf_alloc_copy failed");
2075 	return ret;
2076 fail:
2077 	os_free(der);
2078 	return NULL;
2079 }
2080 
2081 
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)2082 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
2083 				   size_t len, const u8 *sig, size_t sig_len)
2084 {
2085 	int res = 0;
2086 
2087 	if (!key || !key->eckey || !data || len == 0 || !sig || sig_len == 0) {
2088 		wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
2089 			   __func__);
2090 		return -1;
2091 	}
2092 
2093 	if (wc_ecc_verify_hash(sig, sig_len, data, len, &res, key->eckey) != 0)
2094 	{
2095 		wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_verify_hash failed");
2096 		return -1;
2097 	}
2098 
2099 	if (res != 1)
2100 		wpa_printf(MSG_DEBUG,
2101 			   "wolfSSL: crypto_ec_key_verify_signature failed");
2102 
2103 	return res;
2104 }
2105 
2106 #endif /* CONFIG_ECC */
2107 
2108 
crypto_unload(void)2109 void crypto_unload(void)
2110 {
2111 }
2112