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
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
698 #ifdef CONFIG_WPS_NFC
699
dh5_init_fixed(const struct wpabuf * priv,const struct wpabuf * publ)700 void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
701 {
702 DhKey *ret = NULL;
703 DhKey *dh;
704 byte *secret;
705 word32 secret_sz;
706
707 dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
708 if (!dh)
709 return NULL;
710 wc_InitDhKey(dh);
711
712 secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
713 if (!secret)
714 goto done;
715
716 if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
717 RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
718 != 0)
719 goto done;
720
721 if (wc_DhAgree(dh, secret, &secret_sz, wpabuf_head(priv),
722 wpabuf_len(priv), RFC3526_GENERATOR_1536,
723 sizeof(RFC3526_GENERATOR_1536)) != 0)
724 goto done;
725
726 if (secret_sz != wpabuf_len(publ) ||
727 os_memcmp(secret, wpabuf_head(publ), secret_sz) != 0)
728 goto done;
729
730 ret = dh;
731 dh = NULL;
732 done:
733 if (dh) {
734 wc_FreeDhKey(dh);
735 XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
736 }
737 XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
738 return ret;
739 }
740
741 #endif /* CONFIG_WPS_NFC */
742
743
dh5_derive_shared(void * ctx,const struct wpabuf * peer_public,const struct wpabuf * own_private)744 struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
745 const struct wpabuf *own_private)
746 {
747 struct wpabuf *ret = NULL;
748 struct wpabuf *secret;
749 word32 secret_sz;
750
751 secret = wpabuf_alloc(RFC3526_LEN);
752 if (!secret)
753 goto done;
754
755 if (wc_DhAgree(ctx, wpabuf_mhead(secret), &secret_sz,
756 wpabuf_head(own_private), wpabuf_len(own_private),
757 wpabuf_head(peer_public), wpabuf_len(peer_public)) != 0)
758 goto done;
759
760 wpabuf_put(secret, secret_sz);
761
762 ret = secret;
763 secret = NULL;
764 done:
765 wpabuf_clear_free(secret);
766 return ret;
767 }
768
769
dh5_free(void * ctx)770 void dh5_free(void *ctx)
771 {
772 if (!ctx)
773 return;
774
775 wc_FreeDhKey(ctx);
776 XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
777 }
778
779 #endif /* CONFIG_WPS */
780
781
crypto_dh_init(u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)782 int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
783 u8 *pubkey)
784 {
785 int ret = -1;
786 WC_RNG rng;
787 DhKey *dh = NULL;
788 word32 priv_sz, pub_sz;
789
790 if (TEST_FAIL())
791 return -1;
792
793 dh = os_malloc(sizeof(DhKey));
794 if (!dh)
795 return -1;
796 wc_InitDhKey(dh);
797
798 if (wc_InitRng(&rng) != 0) {
799 os_free(dh);
800 return -1;
801 }
802
803 if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
804 goto done;
805
806 if (wc_DhGenerateKeyPair(dh, &rng, privkey, &priv_sz, pubkey, &pub_sz)
807 != 0)
808 goto done;
809
810 if (priv_sz < prime_len) {
811 size_t pad_sz = prime_len - priv_sz;
812
813 os_memmove(privkey + pad_sz, privkey, priv_sz);
814 os_memset(privkey, 0, pad_sz);
815 }
816
817 if (pub_sz < prime_len) {
818 size_t pad_sz = prime_len - pub_sz;
819
820 os_memmove(pubkey + pad_sz, pubkey, pub_sz);
821 os_memset(pubkey, 0, pad_sz);
822 }
823 ret = 0;
824 done:
825 wc_FreeDhKey(dh);
826 os_free(dh);
827 wc_FreeRng(&rng);
828 return ret;
829 }
830
831
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)832 int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len,
833 const u8 *order, size_t order_len,
834 const u8 *privkey, size_t privkey_len,
835 const u8 *pubkey, size_t pubkey_len,
836 u8 *secret, size_t *len)
837 {
838 int ret = -1;
839 DhKey *dh;
840 word32 secret_sz;
841
842 dh = os_malloc(sizeof(DhKey));
843 if (!dh)
844 return -1;
845 wc_InitDhKey(dh);
846
847 if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
848 goto done;
849
850 if (wc_DhAgree(dh, secret, &secret_sz, privkey, privkey_len, pubkey,
851 pubkey_len) != 0)
852 goto done;
853
854 *len = secret_sz;
855 ret = 0;
856 done:
857 wc_FreeDhKey(dh);
858 os_free(dh);
859 return ret;
860 }
861
862
863 #ifdef CONFIG_FIPS
crypto_get_random(void * buf,size_t len)864 int crypto_get_random(void *buf, size_t len)
865 {
866 int ret = 0;
867 WC_RNG rng;
868
869 if (wc_InitRng(&rng) != 0)
870 return -1;
871 if (wc_RNG_GenerateBlock(&rng, buf, len) != 0)
872 ret = -1;
873 wc_FreeRng(&rng);
874 return ret;
875 }
876 #endif /* CONFIG_FIPS */
877
878
879 #if defined(EAP_PWD) || defined(EAP_SERVER_PWD)
880 struct crypto_hash {
881 Hmac hmac;
882 int size;
883 };
884
885
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)886 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
887 size_t key_len)
888 {
889 struct crypto_hash *ret = NULL;
890 struct crypto_hash *hash;
891 int type;
892
893 hash = os_zalloc(sizeof(*hash));
894 if (!hash)
895 goto done;
896
897 switch (alg) {
898 #ifndef NO_MD5
899 case CRYPTO_HASH_ALG_HMAC_MD5:
900 hash->size = 16;
901 type = WC_MD5;
902 break;
903 #endif /* NO_MD5 */
904 #ifndef NO_SHA
905 case CRYPTO_HASH_ALG_HMAC_SHA1:
906 type = WC_SHA;
907 hash->size = 20;
908 break;
909 #endif /* NO_SHA */
910 #ifdef CONFIG_SHA256
911 #ifndef NO_SHA256
912 case CRYPTO_HASH_ALG_HMAC_SHA256:
913 type = WC_SHA256;
914 hash->size = 32;
915 break;
916 #endif /* NO_SHA256 */
917 #endif /* CONFIG_SHA256 */
918 default:
919 goto done;
920 }
921
922 if (wc_HmacSetKey(&hash->hmac, type, key, key_len) != 0)
923 goto done;
924
925 ret = hash;
926 hash = NULL;
927 done:
928 os_free(hash);
929 return ret;
930 }
931
932
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)933 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
934 {
935 if (!ctx)
936 return;
937 wc_HmacUpdate(&ctx->hmac, data, len);
938 }
939
940
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)941 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
942 {
943 int ret = 0;
944
945 if (!ctx)
946 return -2;
947
948 if (!mac || !len)
949 goto done;
950
951 if (wc_HmacFinal(&ctx->hmac, mac) != 0) {
952 ret = -1;
953 goto done;
954 }
955
956 *len = ctx->size;
957 ret = 0;
958 done:
959 bin_clear_free(ctx, sizeof(*ctx));
960 if (TEST_FAIL())
961 return -1;
962 return ret;
963 }
964
965 #endif
966
967
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)968 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
969 const u8 *addr[], const size_t *len, u8 *mac)
970 {
971 Cmac cmac;
972 size_t i;
973 word32 sz;
974
975 if (TEST_FAIL())
976 return -1;
977
978 if (wc_InitCmac(&cmac, key, key_len, WC_CMAC_AES, NULL) != 0)
979 return -1;
980
981 for (i = 0; i < num_elem; i++)
982 if (wc_CmacUpdate(&cmac, addr[i], len[i]) != 0)
983 return -1;
984
985 sz = AES_BLOCK_SIZE;
986 if (wc_CmacFinal(&cmac, mac, &sz) != 0 || sz != AES_BLOCK_SIZE)
987 return -1;
988
989 return 0;
990 }
991
992
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)993 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
994 const u8 *addr[], const size_t *len, u8 *mac)
995 {
996 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
997 }
998
999
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1000 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1001 {
1002 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1003 }
1004
1005
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1006 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1007 {
1008 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1009 }
1010
1011
crypto_bignum_init(void)1012 struct crypto_bignum * crypto_bignum_init(void)
1013 {
1014 mp_int *a;
1015
1016 if (TEST_FAIL())
1017 return NULL;
1018
1019 a = os_malloc(sizeof(*a));
1020 if (!a || mp_init(a) != MP_OKAY) {
1021 os_free(a);
1022 a = NULL;
1023 }
1024
1025 return (struct crypto_bignum *) a;
1026 }
1027
1028
crypto_bignum_init_set(const u8 * buf,size_t len)1029 struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
1030 {
1031 mp_int *a;
1032
1033 if (TEST_FAIL())
1034 return NULL;
1035
1036 a = (mp_int *) crypto_bignum_init();
1037 if (!a)
1038 return NULL;
1039
1040 if (mp_read_unsigned_bin(a, buf, len) != MP_OKAY) {
1041 os_free(a);
1042 a = NULL;
1043 }
1044
1045 return (struct crypto_bignum *) a;
1046 }
1047
1048
crypto_bignum_init_uint(unsigned int val)1049 struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
1050 {
1051 mp_int *a;
1052
1053 if (TEST_FAIL())
1054 return NULL;
1055
1056 a = (mp_int *) crypto_bignum_init();
1057 if (!a)
1058 return NULL;
1059
1060 if (mp_set_int(a, val) != MP_OKAY) {
1061 os_free(a);
1062 a = NULL;
1063 }
1064
1065 return (struct crypto_bignum *) a;
1066 }
1067
1068
crypto_bignum_deinit(struct crypto_bignum * n,int clear)1069 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1070 {
1071 if (!n)
1072 return;
1073
1074 if (clear)
1075 mp_forcezero((mp_int *) n);
1076 mp_clear((mp_int *) n);
1077 os_free((mp_int *) n);
1078 }
1079
1080
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)1081 int crypto_bignum_to_bin(const struct crypto_bignum *a,
1082 u8 *buf, size_t buflen, size_t padlen)
1083 {
1084 int num_bytes, offset;
1085
1086 if (TEST_FAIL())
1087 return -1;
1088
1089 if (padlen > buflen)
1090 return -1;
1091
1092 num_bytes = (mp_count_bits((mp_int *) a) + 7) / 8;
1093 if ((size_t) num_bytes > buflen)
1094 return -1;
1095 if (padlen > (size_t) num_bytes)
1096 offset = padlen - num_bytes;
1097 else
1098 offset = 0;
1099
1100 os_memset(buf, 0, offset);
1101 mp_to_unsigned_bin((mp_int *) a, buf + offset);
1102
1103 return num_bytes + offset;
1104 }
1105
1106
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)1107 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
1108 {
1109 int ret = 0;
1110 WC_RNG rng;
1111 size_t len;
1112 u8 *buf;
1113
1114 if (TEST_FAIL())
1115 return -1;
1116 if (wc_InitRng(&rng) != 0)
1117 return -1;
1118 len = (mp_count_bits((mp_int *) m) + 7) / 8;
1119 buf = os_malloc(len);
1120 if (!buf || wc_RNG_GenerateBlock(&rng, buf, len) != 0 ||
1121 mp_read_unsigned_bin((mp_int *) r, buf, len) != MP_OKAY ||
1122 mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0)
1123 ret = -1;
1124 wc_FreeRng(&rng);
1125 bin_clear_free(buf, len);
1126 return ret;
1127 }
1128
1129
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)1130 int crypto_bignum_add(const struct crypto_bignum *a,
1131 const struct crypto_bignum *b,
1132 struct crypto_bignum *r)
1133 {
1134 return mp_add((mp_int *) a, (mp_int *) b,
1135 (mp_int *) r) == MP_OKAY ? 0 : -1;
1136 }
1137
1138
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)1139 int crypto_bignum_mod(const struct crypto_bignum *a,
1140 const struct crypto_bignum *m,
1141 struct crypto_bignum *r)
1142 {
1143 return mp_mod((mp_int *) a, (mp_int *) m,
1144 (mp_int *) r) == MP_OKAY ? 0 : -1;
1145 }
1146
1147
crypto_bignum_exptmod(const struct crypto_bignum * b,const struct crypto_bignum * e,const struct crypto_bignum * m,struct crypto_bignum * r)1148 int crypto_bignum_exptmod(const struct crypto_bignum *b,
1149 const struct crypto_bignum *e,
1150 const struct crypto_bignum *m,
1151 struct crypto_bignum *r)
1152 {
1153 if (TEST_FAIL())
1154 return -1;
1155
1156 return mp_exptmod((mp_int *) b, (mp_int *) e, (mp_int *) m,
1157 (mp_int *) r) == MP_OKAY ? 0 : -1;
1158 }
1159
1160
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)1161 int crypto_bignum_inverse(const struct crypto_bignum *a,
1162 const struct crypto_bignum *m,
1163 struct crypto_bignum *r)
1164 {
1165 if (TEST_FAIL())
1166 return -1;
1167
1168 return mp_invmod((mp_int *) a, (mp_int *) m,
1169 (mp_int *) r) == MP_OKAY ? 0 : -1;
1170 }
1171
1172
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)1173 int crypto_bignum_sub(const struct crypto_bignum *a,
1174 const struct crypto_bignum *b,
1175 struct crypto_bignum *r)
1176 {
1177 if (TEST_FAIL())
1178 return -1;
1179
1180 return mp_sub((mp_int *) a, (mp_int *) b,
1181 (mp_int *) r) == MP_OKAY ? 0 : -1;
1182 }
1183
1184
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * d)1185 int crypto_bignum_div(const struct crypto_bignum *a,
1186 const struct crypto_bignum *b,
1187 struct crypto_bignum *d)
1188 {
1189 if (TEST_FAIL())
1190 return -1;
1191
1192 return mp_div((mp_int *) a, (mp_int *) b, (mp_int *) d,
1193 NULL) == MP_OKAY ? 0 : -1;
1194 }
1195
1196
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)1197 int crypto_bignum_addmod(const struct crypto_bignum *a,
1198 const struct crypto_bignum *b,
1199 const struct crypto_bignum *c,
1200 struct crypto_bignum *d)
1201 {
1202 if (TEST_FAIL())
1203 return -1;
1204
1205 return mp_addmod((mp_int *) a, (mp_int *) b, (mp_int *) c,
1206 (mp_int *) d) == MP_OKAY ? 0 : -1;
1207 }
1208
1209
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * m,struct crypto_bignum * d)1210 int crypto_bignum_mulmod(const struct crypto_bignum *a,
1211 const struct crypto_bignum *b,
1212 const struct crypto_bignum *m,
1213 struct crypto_bignum *d)
1214 {
1215 if (TEST_FAIL())
1216 return -1;
1217
1218 return mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) m,
1219 (mp_int *) d) == MP_OKAY ? 0 : -1;
1220 }
1221
1222
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1223 int crypto_bignum_sqrmod(const struct crypto_bignum *a,
1224 const struct crypto_bignum *b,
1225 struct crypto_bignum *c)
1226 {
1227 if (TEST_FAIL())
1228 return -1;
1229
1230 return mp_sqrmod((mp_int *) a, (mp_int *) b,
1231 (mp_int *) c) == MP_OKAY ? 0 : -1;
1232 }
1233
1234
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)1235 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1236 struct crypto_bignum *r)
1237 {
1238 if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1239 return -1;
1240 mp_rshb((mp_int *) r, n);
1241 return 0;
1242 }
1243
1244
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)1245 int crypto_bignum_cmp(const struct crypto_bignum *a,
1246 const struct crypto_bignum *b)
1247 {
1248 return mp_cmp((mp_int *) a, (mp_int *) b);
1249 }
1250
1251
crypto_bignum_is_zero(const struct crypto_bignum * a)1252 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1253 {
1254 return mp_iszero((mp_int *) a);
1255 }
1256
1257
crypto_bignum_is_one(const struct crypto_bignum * a)1258 int crypto_bignum_is_one(const struct crypto_bignum *a)
1259 {
1260 return mp_isone((const mp_int *) a);
1261 }
1262
crypto_bignum_is_odd(const struct crypto_bignum * a)1263 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1264 {
1265 return mp_isodd((mp_int *) a);
1266 }
1267
1268
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)1269 int crypto_bignum_legendre(const struct crypto_bignum *a,
1270 const struct crypto_bignum *p)
1271 {
1272 mp_int t;
1273 int ret;
1274 int res = -2;
1275
1276 if (TEST_FAIL())
1277 return -2;
1278
1279 if (mp_init(&t) != MP_OKAY)
1280 return -2;
1281
1282 /* t = (p-1) / 2 */
1283 ret = mp_sub_d((mp_int *) p, 1, &t);
1284 if (ret == MP_OKAY)
1285 mp_rshb(&t, 1);
1286 if (ret == MP_OKAY)
1287 ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1288 if (ret == MP_OKAY) {
1289 if (mp_isone(&t))
1290 res = 1;
1291 else if (mp_iszero(&t))
1292 res = 0;
1293 else
1294 res = -1;
1295 }
1296
1297 mp_clear(&t);
1298 return res;
1299 }
1300
1301
1302 #ifdef CONFIG_ECC
1303
1304 int ecc_map(ecc_point *, mp_int *, mp_digit);
1305 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1306 mp_int *a, mp_int *modulus, mp_digit mp);
1307
1308 struct crypto_ec {
1309 ecc_key key;
1310 mp_int a;
1311 mp_int prime;
1312 mp_int order;
1313 mp_digit mont_b;
1314 mp_int b;
1315 };
1316
1317
crypto_ec_init(int group)1318 struct crypto_ec * crypto_ec_init(int group)
1319 {
1320 int built = 0;
1321 struct crypto_ec *e;
1322 int curve_id;
1323
1324 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1325 switch (group) {
1326 case 19:
1327 curve_id = ECC_SECP256R1;
1328 break;
1329 case 20:
1330 curve_id = ECC_SECP384R1;
1331 break;
1332 case 21:
1333 curve_id = ECC_SECP521R1;
1334 break;
1335 case 25:
1336 curve_id = ECC_SECP192R1;
1337 break;
1338 case 26:
1339 curve_id = ECC_SECP224R1;
1340 break;
1341 #ifdef HAVE_ECC_BRAINPOOL
1342 case 27:
1343 curve_id = ECC_BRAINPOOLP224R1;
1344 break;
1345 case 28:
1346 curve_id = ECC_BRAINPOOLP256R1;
1347 break;
1348 case 29:
1349 curve_id = ECC_BRAINPOOLP384R1;
1350 break;
1351 case 30:
1352 curve_id = ECC_BRAINPOOLP512R1;
1353 break;
1354 #endif /* HAVE_ECC_BRAINPOOL */
1355 default:
1356 return NULL;
1357 }
1358
1359 e = os_zalloc(sizeof(*e));
1360 if (!e)
1361 return NULL;
1362
1363 if (wc_ecc_init(&e->key) != 0 ||
1364 wc_ecc_set_curve(&e->key, 0, curve_id) != 0 ||
1365 mp_init(&e->a) != MP_OKAY ||
1366 mp_init(&e->prime) != MP_OKAY ||
1367 mp_init(&e->order) != MP_OKAY ||
1368 mp_init(&e->b) != MP_OKAY ||
1369 mp_read_radix(&e->a, e->key.dp->Af, 16) != MP_OKAY ||
1370 mp_read_radix(&e->b, e->key.dp->Bf, 16) != MP_OKAY ||
1371 mp_read_radix(&e->prime, e->key.dp->prime, 16) != MP_OKAY ||
1372 mp_read_radix(&e->order, e->key.dp->order, 16) != MP_OKAY ||
1373 mp_montgomery_setup(&e->prime, &e->mont_b) != MP_OKAY)
1374 goto done;
1375
1376 built = 1;
1377 done:
1378 if (!built) {
1379 crypto_ec_deinit(e);
1380 e = NULL;
1381 }
1382 return e;
1383 }
1384
1385
crypto_ec_deinit(struct crypto_ec * e)1386 void crypto_ec_deinit(struct crypto_ec* e)
1387 {
1388 if (!e)
1389 return;
1390
1391 mp_clear(&e->b);
1392 mp_clear(&e->order);
1393 mp_clear(&e->prime);
1394 mp_clear(&e->a);
1395 wc_ecc_free(&e->key);
1396 os_free(e);
1397 }
1398
1399
crypto_ec_point_init(struct crypto_ec * e)1400 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1401 {
1402 if (TEST_FAIL())
1403 return NULL;
1404 if (!e)
1405 return NULL;
1406 return (struct crypto_ec_point *) wc_ecc_new_point();
1407 }
1408
1409
crypto_ec_prime_len(struct crypto_ec * e)1410 size_t crypto_ec_prime_len(struct crypto_ec *e)
1411 {
1412 return (mp_count_bits(&e->prime) + 7) / 8;
1413 }
1414
1415
crypto_ec_prime_len_bits(struct crypto_ec * e)1416 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1417 {
1418 return mp_count_bits(&e->prime);
1419 }
1420
1421
crypto_ec_order_len(struct crypto_ec * e)1422 size_t crypto_ec_order_len(struct crypto_ec *e)
1423 {
1424 return (mp_count_bits(&e->order) + 7) / 8;
1425 }
1426
1427
crypto_ec_get_prime(struct crypto_ec * e)1428 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1429 {
1430 return (const struct crypto_bignum *) &e->prime;
1431 }
1432
1433
crypto_ec_get_order(struct crypto_ec * e)1434 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1435 {
1436 return (const struct crypto_bignum *) &e->order;
1437 }
1438
1439
crypto_ec_get_a(struct crypto_ec * e)1440 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1441 {
1442 return (const struct crypto_bignum *) &e->a;
1443 }
1444
1445
crypto_ec_get_b(struct crypto_ec * e)1446 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1447 {
1448 return (const struct crypto_bignum *) &e->b;
1449 }
1450
1451
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)1452 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1453 {
1454 ecc_point *point = (ecc_point *) p;
1455
1456 if (!p)
1457 return;
1458
1459 if (clear) {
1460 mp_forcezero(point->x);
1461 mp_forcezero(point->y);
1462 mp_forcezero(point->z);
1463 }
1464 wc_ecc_del_point(point);
1465 }
1466
1467
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)1468 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1469 struct crypto_bignum *x)
1470 {
1471 return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1472 }
1473
1474
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)1475 int crypto_ec_point_to_bin(struct crypto_ec *e,
1476 const struct crypto_ec_point *point, u8 *x, u8 *y)
1477 {
1478 ecc_point *p = (ecc_point *) point;
1479
1480 if (TEST_FAIL())
1481 return -1;
1482
1483 if (!mp_isone(p->z)) {
1484 if (ecc_map(p, &e->prime, e->mont_b) != MP_OKAY)
1485 return -1;
1486 }
1487
1488 if (x) {
1489 if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1490 e->key.dp->size,
1491 e->key.dp->size) <= 0)
1492 return -1;
1493 }
1494
1495 if (y) {
1496 if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1497 e->key.dp->size,
1498 e->key.dp->size) <= 0)
1499 return -1;
1500 }
1501
1502 return 0;
1503 }
1504
1505
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)1506 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1507 const u8 *val)
1508 {
1509 ecc_point *point = NULL;
1510 int loaded = 0;
1511
1512 if (TEST_FAIL())
1513 return NULL;
1514
1515 point = wc_ecc_new_point();
1516 if (!point)
1517 goto done;
1518
1519 if (mp_read_unsigned_bin(point->x, val, e->key.dp->size) != MP_OKAY)
1520 goto done;
1521 val += e->key.dp->size;
1522 if (mp_read_unsigned_bin(point->y, val, e->key.dp->size) != MP_OKAY)
1523 goto done;
1524 mp_set(point->z, 1);
1525
1526 loaded = 1;
1527 done:
1528 if (!loaded) {
1529 wc_ecc_del_point(point);
1530 point = NULL;
1531 }
1532 return (struct crypto_ec_point *) point;
1533 }
1534
1535
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)1536 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1537 const struct crypto_ec_point *b,
1538 struct crypto_ec_point *c)
1539 {
1540 mp_int mu;
1541 ecc_point *ta = NULL, *tb = NULL;
1542 ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1543 mp_int *modulus = &e->prime;
1544 int ret;
1545
1546 if (TEST_FAIL())
1547 return -1;
1548
1549 ret = mp_init(&mu);
1550 if (ret != MP_OKAY)
1551 return -1;
1552
1553 ret = mp_montgomery_calc_normalization(&mu, modulus);
1554 if (ret != MP_OKAY) {
1555 mp_clear(&mu);
1556 return -1;
1557 }
1558
1559 if (!mp_isone(&mu)) {
1560 ta = wc_ecc_new_point();
1561 if (!ta) {
1562 mp_clear(&mu);
1563 return -1;
1564 }
1565 tb = wc_ecc_new_point();
1566 if (!tb) {
1567 wc_ecc_del_point(ta);
1568 mp_clear(&mu);
1569 return -1;
1570 }
1571
1572 if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1573 mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1574 mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1575 mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1576 mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1577 mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1578 ret = -1;
1579 goto end;
1580 }
1581 pa = ta;
1582 pb = tb;
1583 }
1584
1585 ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1586 &e->prime, e->mont_b);
1587 if (ret != 0) {
1588 ret = -1;
1589 goto end;
1590 }
1591
1592 if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1593 ret = -1;
1594 else
1595 ret = 0;
1596 end:
1597 wc_ecc_del_point(tb);
1598 wc_ecc_del_point(ta);
1599 mp_clear(&mu);
1600 return ret;
1601 }
1602
1603
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)1604 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1605 const struct crypto_bignum *b,
1606 struct crypto_ec_point *res)
1607 {
1608 int ret;
1609
1610 if (TEST_FAIL())
1611 return -1;
1612
1613 ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
1614 &e->a, &e->prime, 1);
1615 return ret == 0 ? 0 : -1;
1616 }
1617
1618
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)1619 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1620 {
1621 ecc_point *point = (ecc_point *) p;
1622
1623 if (TEST_FAIL())
1624 return -1;
1625
1626 if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
1627 return -1;
1628
1629 return 0;
1630 }
1631
1632
1633 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)1634 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1635 const struct crypto_bignum *x)
1636 {
1637 mp_int *y2 = NULL;
1638 mp_int t;
1639 int calced = 0;
1640
1641 if (TEST_FAIL())
1642 return NULL;
1643
1644 if (mp_init(&t) != MP_OKAY)
1645 return NULL;
1646
1647 y2 = (mp_int *) crypto_bignum_init();
1648 if (!y2)
1649 goto done;
1650
1651 if (mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
1652 mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
1653 mp_mulmod((mp_int *) x, &e->a, &e->prime, &t) != 0 ||
1654 mp_addmod(y2, &t, &e->prime, y2) != 0 ||
1655 mp_addmod(y2, &e->b, &e->prime, y2) != 0)
1656 goto done;
1657
1658 calced = 1;
1659 done:
1660 if (!calced) {
1661 if (y2) {
1662 mp_clear(y2);
1663 os_free(y2);
1664 }
1665 mp_clear(&t);
1666 }
1667
1668 return (struct crypto_bignum *) y2;
1669 }
1670
1671
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)1672 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1673 const struct crypto_ec_point *p)
1674 {
1675 return wc_ecc_point_is_at_infinity((ecc_point *) p);
1676 }
1677
1678
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)1679 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1680 const struct crypto_ec_point *p)
1681 {
1682 return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
1683 MP_OKAY;
1684 }
1685
1686
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)1687 int crypto_ec_point_cmp(const struct crypto_ec *e,
1688 const struct crypto_ec_point *a,
1689 const struct crypto_ec_point *b)
1690 {
1691 return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
1692 }
1693
1694
1695 struct crypto_ecdh {
1696 struct crypto_ec *ec;
1697 };
1698
crypto_ecdh_init(int group)1699 struct crypto_ecdh * crypto_ecdh_init(int group)
1700 {
1701 struct crypto_ecdh *ecdh = NULL;
1702 WC_RNG rng;
1703 int ret;
1704
1705 if (wc_InitRng(&rng) != 0)
1706 goto fail;
1707
1708 ecdh = os_zalloc(sizeof(*ecdh));
1709 if (!ecdh)
1710 goto fail;
1711
1712 ecdh->ec = crypto_ec_init(group);
1713 if (!ecdh->ec)
1714 goto fail;
1715
1716 ret = wc_ecc_make_key_ex(&rng, ecdh->ec->key.dp->size, &ecdh->ec->key,
1717 ecdh->ec->key.dp->id);
1718 if (ret < 0)
1719 goto fail;
1720
1721 done:
1722 wc_FreeRng(&rng);
1723
1724 return ecdh;
1725 fail:
1726 crypto_ecdh_deinit(ecdh);
1727 ecdh = NULL;
1728 goto done;
1729 }
1730
1731
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)1732 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
1733 {
1734 if (ecdh) {
1735 crypto_ec_deinit(ecdh->ec);
1736 os_free(ecdh);
1737 }
1738 }
1739
1740
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)1741 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
1742 {
1743 struct wpabuf *buf = NULL;
1744 int ret;
1745 int len = ecdh->ec->key.dp->size;
1746
1747 buf = wpabuf_alloc(inc_y ? 2 * len : len);
1748 if (!buf)
1749 goto fail;
1750
1751 ret = crypto_bignum_to_bin((struct crypto_bignum *)
1752 ecdh->ec->key.pubkey.x, wpabuf_put(buf, len),
1753 len, len);
1754 if (ret < 0)
1755 goto fail;
1756 if (inc_y) {
1757 ret = crypto_bignum_to_bin((struct crypto_bignum *)
1758 ecdh->ec->key.pubkey.y,
1759 wpabuf_put(buf, len), len, len);
1760 if (ret < 0)
1761 goto fail;
1762 }
1763
1764 done:
1765 return buf;
1766 fail:
1767 wpabuf_free(buf);
1768 buf = NULL;
1769 goto done;
1770 }
1771
1772
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)1773 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
1774 const u8 *key, size_t len)
1775 {
1776 int ret;
1777 struct wpabuf *pubkey = NULL;
1778 struct wpabuf *secret = NULL;
1779 word32 key_len = ecdh->ec->key.dp->size;
1780 ecc_point *point = NULL;
1781 size_t need_key_len = inc_y ? 2 * key_len : key_len;
1782
1783 if (len < need_key_len)
1784 goto fail;
1785 pubkey = wpabuf_alloc(1 + 2 * key_len);
1786 if (!pubkey)
1787 goto fail;
1788 wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
1789 wpabuf_put_data(pubkey, key, need_key_len);
1790
1791 point = wc_ecc_new_point();
1792 if (!point)
1793 goto fail;
1794
1795 ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
1796 ecdh->ec->key.idx, point);
1797 if (ret != MP_OKAY)
1798 goto fail;
1799
1800 secret = wpabuf_alloc(key_len);
1801 if (!secret)
1802 goto fail;
1803
1804 ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point,
1805 wpabuf_put(secret, key_len), &key_len);
1806 if (ret != MP_OKAY)
1807 goto fail;
1808
1809 done:
1810 wc_ecc_del_point(point);
1811 wpabuf_free(pubkey);
1812 return secret;
1813 fail:
1814 wpabuf_free(secret);
1815 secret = NULL;
1816 goto done;
1817 }
1818
1819
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)1820 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
1821 {
1822 return crypto_ec_prime_len(ecdh->ec);
1823 }
1824
1825 #endif /* CONFIG_ECC */
1826