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