]> git.ipfire.org Git - thirdparty/hostap.git/blob - src/crypto/crypto_wolfssl.c
WPS: Make it possible to use PSKs loaded from the PSK file
[thirdparty/hostap.git] / src / crypto / crypto_wolfssl.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
328 int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
329 {
330 wc_AesEncryptDirect(ctx, crypt, plain);
331 return 0;
332 }
333
334
335 void aes_encrypt_deinit(void *ctx)
336 {
337 os_free(ctx);
338 }
339
340
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
361 int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
362 {
363 wc_AesDecryptDirect(ctx, plain, crypt);
364 return 0;
365 }
366
367
368 void aes_decrypt_deinit(void *ctx)
369 {
370 os_free(ctx);
371 }
372
373
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1045 struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
1046 {
1047 mp_int *a;
1048
1049 if (TEST_FAIL())
1050 return NULL;
1051
1052 a = (mp_int *) crypto_bignum_init();
1053 if (!a)
1054 return NULL;
1055
1056 if (mp_set_int(a, val) != MP_OKAY) {
1057 os_free(a);
1058 a = NULL;
1059 }
1060
1061 return (struct crypto_bignum *) a;
1062 }
1063
1064
1065 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1066 {
1067 if (!n)
1068 return;
1069
1070 if (clear)
1071 mp_forcezero((mp_int *) n);
1072 mp_clear((mp_int *) n);
1073 os_free((mp_int *) n);
1074 }
1075
1076
1077 int crypto_bignum_to_bin(const struct crypto_bignum *a,
1078 u8 *buf, size_t buflen, size_t padlen)
1079 {
1080 int num_bytes, offset;
1081
1082 if (TEST_FAIL())
1083 return -1;
1084
1085 if (padlen > buflen)
1086 return -1;
1087
1088 num_bytes = (mp_count_bits((mp_int *) a) + 7) / 8;
1089 if ((size_t) num_bytes > buflen)
1090 return -1;
1091 if (padlen > (size_t) num_bytes)
1092 offset = padlen - num_bytes;
1093 else
1094 offset = 0;
1095
1096 os_memset(buf, 0, offset);
1097 mp_to_unsigned_bin((mp_int *) a, buf + offset);
1098
1099 return num_bytes + offset;
1100 }
1101
1102
1103 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
1104 {
1105 int ret = 0;
1106 WC_RNG rng;
1107
1108 if (TEST_FAIL())
1109 return -1;
1110 if (wc_InitRng(&rng) != 0)
1111 return -1;
1112 if (mp_rand_prime((mp_int *) r,
1113 (mp_count_bits((mp_int *) m) + 7) / 8 * 2,
1114 &rng, NULL) != 0)
1115 ret = -1;
1116 if (ret == 0 &&
1117 mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0)
1118 ret = -1;
1119 wc_FreeRng(&rng);
1120 return ret;
1121 }
1122
1123
1124 int crypto_bignum_add(const struct crypto_bignum *a,
1125 const struct crypto_bignum *b,
1126 struct crypto_bignum *r)
1127 {
1128 return mp_add((mp_int *) a, (mp_int *) b,
1129 (mp_int *) r) == MP_OKAY ? 0 : -1;
1130 }
1131
1132
1133 int crypto_bignum_mod(const struct crypto_bignum *a,
1134 const struct crypto_bignum *m,
1135 struct crypto_bignum *r)
1136 {
1137 return mp_mod((mp_int *) a, (mp_int *) m,
1138 (mp_int *) r) == MP_OKAY ? 0 : -1;
1139 }
1140
1141
1142 int crypto_bignum_exptmod(const struct crypto_bignum *b,
1143 const struct crypto_bignum *e,
1144 const struct crypto_bignum *m,
1145 struct crypto_bignum *r)
1146 {
1147 if (TEST_FAIL())
1148 return -1;
1149
1150 return mp_exptmod((mp_int *) b, (mp_int *) e, (mp_int *) m,
1151 (mp_int *) r) == MP_OKAY ? 0 : -1;
1152 }
1153
1154
1155 int crypto_bignum_inverse(const struct crypto_bignum *a,
1156 const struct crypto_bignum *m,
1157 struct crypto_bignum *r)
1158 {
1159 if (TEST_FAIL())
1160 return -1;
1161
1162 return mp_invmod((mp_int *) a, (mp_int *) m,
1163 (mp_int *) r) == MP_OKAY ? 0 : -1;
1164 }
1165
1166
1167 int crypto_bignum_sub(const struct crypto_bignum *a,
1168 const struct crypto_bignum *b,
1169 struct crypto_bignum *r)
1170 {
1171 if (TEST_FAIL())
1172 return -1;
1173
1174 return mp_sub((mp_int *) a, (mp_int *) b,
1175 (mp_int *) r) == MP_OKAY ? 0 : -1;
1176 }
1177
1178
1179 int crypto_bignum_div(const struct crypto_bignum *a,
1180 const struct crypto_bignum *b,
1181 struct crypto_bignum *d)
1182 {
1183 if (TEST_FAIL())
1184 return -1;
1185
1186 return mp_div((mp_int *) a, (mp_int *) b, (mp_int *) d,
1187 NULL) == MP_OKAY ? 0 : -1;
1188 }
1189
1190
1191 int crypto_bignum_addmod(const struct crypto_bignum *a,
1192 const struct crypto_bignum *b,
1193 const struct crypto_bignum *c,
1194 struct crypto_bignum *d)
1195 {
1196 if (TEST_FAIL())
1197 return -1;
1198
1199 return mp_addmod((mp_int *) a, (mp_int *) b, (mp_int *) c,
1200 (mp_int *) d) == MP_OKAY ? 0 : -1;
1201 }
1202
1203
1204 int crypto_bignum_mulmod(const struct crypto_bignum *a,
1205 const struct crypto_bignum *b,
1206 const struct crypto_bignum *m,
1207 struct crypto_bignum *d)
1208 {
1209 if (TEST_FAIL())
1210 return -1;
1211
1212 return mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) m,
1213 (mp_int *) d) == MP_OKAY ? 0 : -1;
1214 }
1215
1216
1217 int crypto_bignum_sqrmod(const struct crypto_bignum *a,
1218 const struct crypto_bignum *b,
1219 struct crypto_bignum *c)
1220 {
1221 if (TEST_FAIL())
1222 return -1;
1223
1224 return mp_sqrmod((mp_int *) a, (mp_int *) b,
1225 (mp_int *) c) == MP_OKAY ? 0 : -1;
1226 }
1227
1228
1229 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1230 struct crypto_bignum *r)
1231 {
1232 if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1233 return -1;
1234 mp_rshb((mp_int *) r, n);
1235 return 0;
1236 }
1237
1238
1239 int crypto_bignum_cmp(const struct crypto_bignum *a,
1240 const struct crypto_bignum *b)
1241 {
1242 return mp_cmp((mp_int *) a, (mp_int *) b);
1243 }
1244
1245
1246 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1247 {
1248 return mp_iszero((mp_int *) a);
1249 }
1250
1251
1252 int crypto_bignum_is_one(const struct crypto_bignum *a)
1253 {
1254 return mp_isone((const mp_int *) a);
1255 }
1256
1257 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1258 {
1259 return mp_isodd((mp_int *) a);
1260 }
1261
1262
1263 int crypto_bignum_legendre(const struct crypto_bignum *a,
1264 const struct crypto_bignum *p)
1265 {
1266 mp_int t;
1267 int ret;
1268 int res = -2;
1269
1270 if (TEST_FAIL())
1271 return -2;
1272
1273 if (mp_init(&t) != MP_OKAY)
1274 return -2;
1275
1276 /* t = (p-1) / 2 */
1277 ret = mp_sub_d((mp_int *) p, 1, &t);
1278 if (ret == MP_OKAY)
1279 mp_rshb(&t, 1);
1280 if (ret == MP_OKAY)
1281 ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1282 if (ret == MP_OKAY) {
1283 if (mp_isone(&t))
1284 res = 1;
1285 else if (mp_iszero(&t))
1286 res = 0;
1287 else
1288 res = -1;
1289 }
1290
1291 mp_clear(&t);
1292 return res;
1293 }
1294
1295
1296 #ifdef CONFIG_ECC
1297
1298 int ecc_map(ecc_point *, mp_int *, mp_digit);
1299 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1300 mp_int *a, mp_int *modulus, mp_digit mp);
1301
1302 struct crypto_ec {
1303 ecc_key key;
1304 mp_int a;
1305 mp_int prime;
1306 mp_int order;
1307 mp_digit mont_b;
1308 mp_int b;
1309 };
1310
1311
1312 struct crypto_ec * crypto_ec_init(int group)
1313 {
1314 int built = 0;
1315 struct crypto_ec *e;
1316 int curve_id;
1317
1318 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1319 switch (group) {
1320 case 19:
1321 curve_id = ECC_SECP256R1;
1322 break;
1323 case 20:
1324 curve_id = ECC_SECP384R1;
1325 break;
1326 case 21:
1327 curve_id = ECC_SECP521R1;
1328 break;
1329 case 25:
1330 curve_id = ECC_SECP192R1;
1331 break;
1332 case 26:
1333 curve_id = ECC_SECP224R1;
1334 break;
1335 #ifdef HAVE_ECC_BRAINPOOL
1336 case 27:
1337 curve_id = ECC_BRAINPOOLP224R1;
1338 break;
1339 case 28:
1340 curve_id = ECC_BRAINPOOLP256R1;
1341 break;
1342 case 29:
1343 curve_id = ECC_BRAINPOOLP384R1;
1344 break;
1345 case 30:
1346 curve_id = ECC_BRAINPOOLP512R1;
1347 break;
1348 #endif /* HAVE_ECC_BRAINPOOL */
1349 default:
1350 return NULL;
1351 }
1352
1353 e = os_zalloc(sizeof(*e));
1354 if (!e)
1355 return NULL;
1356
1357 if (wc_ecc_init(&e->key) != 0 ||
1358 wc_ecc_set_curve(&e->key, 0, curve_id) != 0 ||
1359 mp_init(&e->a) != MP_OKAY ||
1360 mp_init(&e->prime) != MP_OKAY ||
1361 mp_init(&e->order) != MP_OKAY ||
1362 mp_init(&e->b) != MP_OKAY ||
1363 mp_read_radix(&e->a, e->key.dp->Af, 16) != MP_OKAY ||
1364 mp_read_radix(&e->b, e->key.dp->Bf, 16) != MP_OKAY ||
1365 mp_read_radix(&e->prime, e->key.dp->prime, 16) != MP_OKAY ||
1366 mp_read_radix(&e->order, e->key.dp->order, 16) != MP_OKAY ||
1367 mp_montgomery_setup(&e->prime, &e->mont_b) != MP_OKAY)
1368 goto done;
1369
1370 built = 1;
1371 done:
1372 if (!built) {
1373 crypto_ec_deinit(e);
1374 e = NULL;
1375 }
1376 return e;
1377 }
1378
1379
1380 void crypto_ec_deinit(struct crypto_ec* e)
1381 {
1382 if (!e)
1383 return;
1384
1385 mp_clear(&e->b);
1386 mp_clear(&e->order);
1387 mp_clear(&e->prime);
1388 mp_clear(&e->a);
1389 wc_ecc_free(&e->key);
1390 os_free(e);
1391 }
1392
1393
1394 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1395 {
1396 if (TEST_FAIL())
1397 return NULL;
1398 if (!e)
1399 return NULL;
1400 return (struct crypto_ec_point *) wc_ecc_new_point();
1401 }
1402
1403
1404 size_t crypto_ec_prime_len(struct crypto_ec *e)
1405 {
1406 return (mp_count_bits(&e->prime) + 7) / 8;
1407 }
1408
1409
1410 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1411 {
1412 return mp_count_bits(&e->prime);
1413 }
1414
1415
1416 size_t crypto_ec_order_len(struct crypto_ec *e)
1417 {
1418 return (mp_count_bits(&e->order) + 7) / 8;
1419 }
1420
1421
1422 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1423 {
1424 return (const struct crypto_bignum *) &e->prime;
1425 }
1426
1427
1428 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1429 {
1430 return (const struct crypto_bignum *) &e->order;
1431 }
1432
1433
1434 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1435 {
1436 return (const struct crypto_bignum *) &e->a;
1437 }
1438
1439
1440 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1441 {
1442 return (const struct crypto_bignum *) &e->b;
1443 }
1444
1445
1446 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1447 {
1448 ecc_point *point = (ecc_point *) p;
1449
1450 if (!p)
1451 return;
1452
1453 if (clear) {
1454 mp_forcezero(point->x);
1455 mp_forcezero(point->y);
1456 mp_forcezero(point->z);
1457 }
1458 wc_ecc_del_point(point);
1459 }
1460
1461
1462 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1463 struct crypto_bignum *x)
1464 {
1465 return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1466 }
1467
1468
1469 int crypto_ec_point_to_bin(struct crypto_ec *e,
1470 const struct crypto_ec_point *point, u8 *x, u8 *y)
1471 {
1472 ecc_point *p = (ecc_point *) point;
1473
1474 if (TEST_FAIL())
1475 return -1;
1476
1477 if (!mp_isone(p->z)) {
1478 if (ecc_map(p, &e->prime, e->mont_b) != MP_OKAY)
1479 return -1;
1480 }
1481
1482 if (x) {
1483 if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1484 e->key.dp->size,
1485 e->key.dp->size) <= 0)
1486 return -1;
1487 }
1488
1489 if (y) {
1490 if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1491 e->key.dp->size,
1492 e->key.dp->size) <= 0)
1493 return -1;
1494 }
1495
1496 return 0;
1497 }
1498
1499
1500 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1501 const u8 *val)
1502 {
1503 ecc_point *point = NULL;
1504 int loaded = 0;
1505
1506 if (TEST_FAIL())
1507 return NULL;
1508
1509 point = wc_ecc_new_point();
1510 if (!point)
1511 goto done;
1512
1513 if (mp_read_unsigned_bin(point->x, val, e->key.dp->size) != MP_OKAY)
1514 goto done;
1515 val += e->key.dp->size;
1516 if (mp_read_unsigned_bin(point->y, val, e->key.dp->size) != MP_OKAY)
1517 goto done;
1518 mp_set(point->z, 1);
1519
1520 loaded = 1;
1521 done:
1522 if (!loaded) {
1523 wc_ecc_del_point(point);
1524 point = NULL;
1525 }
1526 return (struct crypto_ec_point *) point;
1527 }
1528
1529
1530 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1531 const struct crypto_ec_point *b,
1532 struct crypto_ec_point *c)
1533 {
1534 mp_int mu;
1535 ecc_point *ta = NULL, *tb = NULL;
1536 ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1537 mp_int *modulus = &e->prime;
1538 int ret;
1539
1540 if (TEST_FAIL())
1541 return -1;
1542
1543 ret = mp_init(&mu);
1544 if (ret != MP_OKAY)
1545 return -1;
1546
1547 ret = mp_montgomery_calc_normalization(&mu, modulus);
1548 if (ret != MP_OKAY) {
1549 mp_clear(&mu);
1550 return -1;
1551 }
1552
1553 if (!mp_isone(&mu)) {
1554 ta = wc_ecc_new_point();
1555 if (!ta) {
1556 mp_clear(&mu);
1557 return -1;
1558 }
1559 tb = wc_ecc_new_point();
1560 if (!tb) {
1561 wc_ecc_del_point(ta);
1562 mp_clear(&mu);
1563 return -1;
1564 }
1565
1566 if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1567 mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1568 mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1569 mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1570 mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1571 mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1572 ret = -1;
1573 goto end;
1574 }
1575 pa = ta;
1576 pb = tb;
1577 }
1578
1579 ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1580 &e->prime, e->mont_b);
1581 if (ret != 0) {
1582 ret = -1;
1583 goto end;
1584 }
1585
1586 if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1587 ret = -1;
1588 else
1589 ret = 0;
1590 end:
1591 wc_ecc_del_point(tb);
1592 wc_ecc_del_point(ta);
1593 mp_clear(&mu);
1594 return ret;
1595 }
1596
1597
1598 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1599 const struct crypto_bignum *b,
1600 struct crypto_ec_point *res)
1601 {
1602 int ret;
1603
1604 if (TEST_FAIL())
1605 return -1;
1606
1607 ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
1608 &e->a, &e->prime, 1);
1609 return ret == 0 ? 0 : -1;
1610 }
1611
1612
1613 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1614 {
1615 ecc_point *point = (ecc_point *) p;
1616
1617 if (TEST_FAIL())
1618 return -1;
1619
1620 if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
1621 return -1;
1622
1623 return 0;
1624 }
1625
1626
1627 int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
1628 struct crypto_ec_point *p,
1629 const struct crypto_bignum *x, int y_bit)
1630 {
1631 byte buf[1 + 2 * MAX_ECC_BYTES];
1632 int ret;
1633 int prime_len = crypto_ec_prime_len(e);
1634
1635 if (TEST_FAIL())
1636 return -1;
1637
1638 buf[0] = y_bit ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
1639 ret = crypto_bignum_to_bin(x, buf + 1, prime_len, prime_len);
1640 if (ret <= 0)
1641 return -1;
1642 ret = wc_ecc_import_point_der(buf, 1 + 2 * ret, e->key.idx,
1643 (ecc_point *) p);
1644 if (ret != 0)
1645 return -1;
1646
1647 return 0;
1648 }
1649
1650
1651 struct crypto_bignum *
1652 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1653 const struct crypto_bignum *x)
1654 {
1655 mp_int *y2 = NULL;
1656 mp_int t;
1657 int calced = 0;
1658
1659 if (TEST_FAIL())
1660 return NULL;
1661
1662 if (mp_init(&t) != MP_OKAY)
1663 return NULL;
1664
1665 y2 = (mp_int *) crypto_bignum_init();
1666 if (!y2)
1667 goto done;
1668
1669 if (mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
1670 mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
1671 mp_mulmod((mp_int *) x, &e->a, &e->prime, &t) != 0 ||
1672 mp_addmod(y2, &t, &e->prime, y2) != 0 ||
1673 mp_addmod(y2, &e->b, &e->prime, y2) != 0)
1674 goto done;
1675
1676 calced = 1;
1677 done:
1678 if (!calced) {
1679 if (y2) {
1680 mp_clear(y2);
1681 os_free(y2);
1682 }
1683 mp_clear(&t);
1684 }
1685
1686 return (struct crypto_bignum *) y2;
1687 }
1688
1689
1690 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1691 const struct crypto_ec_point *p)
1692 {
1693 return wc_ecc_point_is_at_infinity((ecc_point *) p);
1694 }
1695
1696
1697 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1698 const struct crypto_ec_point *p)
1699 {
1700 return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
1701 MP_OKAY;
1702 }
1703
1704
1705 int crypto_ec_point_cmp(const struct crypto_ec *e,
1706 const struct crypto_ec_point *a,
1707 const struct crypto_ec_point *b)
1708 {
1709 return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
1710 }
1711
1712
1713 struct crypto_ecdh {
1714 struct crypto_ec *ec;
1715 };
1716
1717 struct crypto_ecdh * crypto_ecdh_init(int group)
1718 {
1719 struct crypto_ecdh *ecdh = NULL;
1720 WC_RNG rng;
1721 int ret;
1722
1723 if (wc_InitRng(&rng) != 0)
1724 goto fail;
1725
1726 ecdh = os_zalloc(sizeof(*ecdh));
1727 if (!ecdh)
1728 goto fail;
1729
1730 ecdh->ec = crypto_ec_init(group);
1731 if (!ecdh->ec)
1732 goto fail;
1733
1734 ret = wc_ecc_make_key_ex(&rng, ecdh->ec->key.dp->size, &ecdh->ec->key,
1735 ecdh->ec->key.dp->id);
1736 if (ret < 0)
1737 goto fail;
1738
1739 done:
1740 wc_FreeRng(&rng);
1741
1742 return ecdh;
1743 fail:
1744 crypto_ecdh_deinit(ecdh);
1745 ecdh = NULL;
1746 goto done;
1747 }
1748
1749
1750 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
1751 {
1752 if (ecdh) {
1753 crypto_ec_deinit(ecdh->ec);
1754 os_free(ecdh);
1755 }
1756 }
1757
1758
1759 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
1760 {
1761 struct wpabuf *buf = NULL;
1762 int ret;
1763 int len = ecdh->ec->key.dp->size;
1764
1765 buf = wpabuf_alloc(inc_y ? 2 * len : len);
1766 if (!buf)
1767 goto fail;
1768
1769 ret = crypto_bignum_to_bin((struct crypto_bignum *)
1770 ecdh->ec->key.pubkey.x, wpabuf_put(buf, len),
1771 len, len);
1772 if (ret < 0)
1773 goto fail;
1774 if (inc_y) {
1775 ret = crypto_bignum_to_bin((struct crypto_bignum *)
1776 ecdh->ec->key.pubkey.y,
1777 wpabuf_put(buf, len), len, len);
1778 if (ret < 0)
1779 goto fail;
1780 }
1781
1782 done:
1783 return buf;
1784 fail:
1785 wpabuf_free(buf);
1786 buf = NULL;
1787 goto done;
1788 }
1789
1790
1791 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
1792 const u8 *key, size_t len)
1793 {
1794 int ret;
1795 struct wpabuf *pubkey = NULL;
1796 struct wpabuf *secret = NULL;
1797 word32 key_len = ecdh->ec->key.dp->size;
1798 ecc_point *point = NULL;
1799 size_t need_key_len = inc_y ? 2 * key_len : key_len;
1800
1801 if (len < need_key_len)
1802 goto fail;
1803 pubkey = wpabuf_alloc(1 + 2 * key_len);
1804 if (!pubkey)
1805 goto fail;
1806 wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
1807 wpabuf_put_data(pubkey, key, need_key_len);
1808
1809 point = wc_ecc_new_point();
1810 if (!point)
1811 goto fail;
1812
1813 ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
1814 ecdh->ec->key.idx, point);
1815 if (ret != MP_OKAY)
1816 goto fail;
1817
1818 secret = wpabuf_alloc(key_len);
1819 if (!secret)
1820 goto fail;
1821
1822 ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point,
1823 wpabuf_put(secret, key_len), &key_len);
1824 if (ret != MP_OKAY)
1825 goto fail;
1826
1827 done:
1828 wc_ecc_del_point(point);
1829 wpabuf_free(pubkey);
1830 return secret;
1831 fail:
1832 wpabuf_free(secret);
1833 secret = NULL;
1834 goto done;
1835 }
1836
1837 #endif /* CONFIG_ECC */