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