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