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