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