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_sqrtmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1235 int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
1236 const struct crypto_bignum *b,
1237 struct crypto_bignum *c)
1238 {
1239 /* TODO */
1240 return -1;
1241 }
1242
1243
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)1244 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1245 struct crypto_bignum *r)
1246 {
1247 if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1248 return -1;
1249 mp_rshb((mp_int *) r, n);
1250 return 0;
1251 }
1252
1253
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)1254 int crypto_bignum_cmp(const struct crypto_bignum *a,
1255 const struct crypto_bignum *b)
1256 {
1257 return mp_cmp((mp_int *) a, (mp_int *) b);
1258 }
1259
1260
crypto_bignum_is_zero(const struct crypto_bignum * a)1261 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1262 {
1263 return mp_iszero((mp_int *) a);
1264 }
1265
1266
crypto_bignum_is_one(const struct crypto_bignum * a)1267 int crypto_bignum_is_one(const struct crypto_bignum *a)
1268 {
1269 return mp_isone((const mp_int *) a);
1270 }
1271
crypto_bignum_is_odd(const struct crypto_bignum * a)1272 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1273 {
1274 return mp_isodd((mp_int *) a);
1275 }
1276
1277
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)1278 int crypto_bignum_legendre(const struct crypto_bignum *a,
1279 const struct crypto_bignum *p)
1280 {
1281 mp_int t;
1282 int ret;
1283 int res = -2;
1284
1285 if (TEST_FAIL())
1286 return -2;
1287
1288 if (mp_init(&t) != MP_OKAY)
1289 return -2;
1290
1291 /* t = (p-1) / 2 */
1292 ret = mp_sub_d((mp_int *) p, 1, &t);
1293 if (ret == MP_OKAY)
1294 mp_rshb(&t, 1);
1295 if (ret == MP_OKAY)
1296 ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1297 if (ret == MP_OKAY) {
1298 if (mp_isone(&t))
1299 res = 1;
1300 else if (mp_iszero(&t))
1301 res = 0;
1302 else
1303 res = -1;
1304 }
1305
1306 mp_clear(&t);
1307 return res;
1308 }
1309
1310
1311 #ifdef CONFIG_ECC
1312
1313 int ecc_map(ecc_point *, mp_int *, mp_digit);
1314 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1315 mp_int *a, mp_int *modulus, mp_digit mp);
1316
1317 struct crypto_ec {
1318 ecc_key key;
1319 mp_int a;
1320 mp_int prime;
1321 mp_int order;
1322 mp_digit mont_b;
1323 mp_int b;
1324 };
1325
1326
crypto_ec_init(int group)1327 struct crypto_ec * crypto_ec_init(int group)
1328 {
1329 int built = 0;
1330 struct crypto_ec *e;
1331 int curve_id;
1332
1333 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1334 switch (group) {
1335 case 19:
1336 curve_id = ECC_SECP256R1;
1337 break;
1338 case 20:
1339 curve_id = ECC_SECP384R1;
1340 break;
1341 case 21:
1342 curve_id = ECC_SECP521R1;
1343 break;
1344 case 25:
1345 curve_id = ECC_SECP192R1;
1346 break;
1347 case 26:
1348 curve_id = ECC_SECP224R1;
1349 break;
1350 #ifdef HAVE_ECC_BRAINPOOL
1351 case 27:
1352 curve_id = ECC_BRAINPOOLP224R1;
1353 break;
1354 case 28:
1355 curve_id = ECC_BRAINPOOLP256R1;
1356 break;
1357 case 29:
1358 curve_id = ECC_BRAINPOOLP384R1;
1359 break;
1360 case 30:
1361 curve_id = ECC_BRAINPOOLP512R1;
1362 break;
1363 #endif /* HAVE_ECC_BRAINPOOL */
1364 default:
1365 return NULL;
1366 }
1367
1368 e = os_zalloc(sizeof(*e));
1369 if (!e)
1370 return NULL;
1371
1372 if (wc_ecc_init(&e->key) != 0 ||
1373 wc_ecc_set_curve(&e->key, 0, curve_id) != 0 ||
1374 mp_init(&e->a) != MP_OKAY ||
1375 mp_init(&e->prime) != MP_OKAY ||
1376 mp_init(&e->order) != MP_OKAY ||
1377 mp_init(&e->b) != MP_OKAY ||
1378 mp_read_radix(&e->a, e->key.dp->Af, 16) != MP_OKAY ||
1379 mp_read_radix(&e->b, e->key.dp->Bf, 16) != MP_OKAY ||
1380 mp_read_radix(&e->prime, e->key.dp->prime, 16) != MP_OKAY ||
1381 mp_read_radix(&e->order, e->key.dp->order, 16) != MP_OKAY ||
1382 mp_montgomery_setup(&e->prime, &e->mont_b) != MP_OKAY)
1383 goto done;
1384
1385 built = 1;
1386 done:
1387 if (!built) {
1388 crypto_ec_deinit(e);
1389 e = NULL;
1390 }
1391 return e;
1392 }
1393
1394
crypto_ec_deinit(struct crypto_ec * e)1395 void crypto_ec_deinit(struct crypto_ec* e)
1396 {
1397 if (!e)
1398 return;
1399
1400 mp_clear(&e->b);
1401 mp_clear(&e->order);
1402 mp_clear(&e->prime);
1403 mp_clear(&e->a);
1404 wc_ecc_free(&e->key);
1405 os_free(e);
1406 }
1407
1408
crypto_ec_point_init(struct crypto_ec * e)1409 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1410 {
1411 if (TEST_FAIL())
1412 return NULL;
1413 if (!e)
1414 return NULL;
1415 return (struct crypto_ec_point *) wc_ecc_new_point();
1416 }
1417
1418
crypto_ec_prime_len(struct crypto_ec * e)1419 size_t crypto_ec_prime_len(struct crypto_ec *e)
1420 {
1421 return (mp_count_bits(&e->prime) + 7) / 8;
1422 }
1423
1424
crypto_ec_prime_len_bits(struct crypto_ec * e)1425 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1426 {
1427 return mp_count_bits(&e->prime);
1428 }
1429
1430
crypto_ec_order_len(struct crypto_ec * e)1431 size_t crypto_ec_order_len(struct crypto_ec *e)
1432 {
1433 return (mp_count_bits(&e->order) + 7) / 8;
1434 }
1435
1436
crypto_ec_get_prime(struct crypto_ec * e)1437 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1438 {
1439 return (const struct crypto_bignum *) &e->prime;
1440 }
1441
1442
crypto_ec_get_order(struct crypto_ec * e)1443 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1444 {
1445 return (const struct crypto_bignum *) &e->order;
1446 }
1447
1448
crypto_ec_get_a(struct crypto_ec * e)1449 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1450 {
1451 return (const struct crypto_bignum *) &e->a;
1452 }
1453
1454
crypto_ec_get_b(struct crypto_ec * e)1455 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1456 {
1457 return (const struct crypto_bignum *) &e->b;
1458 }
1459
1460
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)1461 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1462 {
1463 ecc_point *point = (ecc_point *) p;
1464
1465 if (!p)
1466 return;
1467
1468 if (clear) {
1469 mp_forcezero(point->x);
1470 mp_forcezero(point->y);
1471 mp_forcezero(point->z);
1472 }
1473 wc_ecc_del_point(point);
1474 }
1475
1476
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)1477 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1478 struct crypto_bignum *x)
1479 {
1480 return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1481 }
1482
1483
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)1484 int crypto_ec_point_to_bin(struct crypto_ec *e,
1485 const struct crypto_ec_point *point, u8 *x, u8 *y)
1486 {
1487 ecc_point *p = (ecc_point *) point;
1488
1489 if (TEST_FAIL())
1490 return -1;
1491
1492 if (!mp_isone(p->z)) {
1493 if (ecc_map(p, &e->prime, e->mont_b) != MP_OKAY)
1494 return -1;
1495 }
1496
1497 if (x) {
1498 if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1499 e->key.dp->size,
1500 e->key.dp->size) <= 0)
1501 return -1;
1502 }
1503
1504 if (y) {
1505 if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1506 e->key.dp->size,
1507 e->key.dp->size) <= 0)
1508 return -1;
1509 }
1510
1511 return 0;
1512 }
1513
1514
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)1515 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1516 const u8 *val)
1517 {
1518 ecc_point *point = NULL;
1519 int loaded = 0;
1520
1521 if (TEST_FAIL())
1522 return NULL;
1523
1524 point = wc_ecc_new_point();
1525 if (!point)
1526 goto done;
1527
1528 if (mp_read_unsigned_bin(point->x, val, e->key.dp->size) != MP_OKAY)
1529 goto done;
1530 val += e->key.dp->size;
1531 if (mp_read_unsigned_bin(point->y, val, e->key.dp->size) != MP_OKAY)
1532 goto done;
1533 mp_set(point->z, 1);
1534
1535 loaded = 1;
1536 done:
1537 if (!loaded) {
1538 wc_ecc_del_point(point);
1539 point = NULL;
1540 }
1541 return (struct crypto_ec_point *) point;
1542 }
1543
1544
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)1545 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1546 const struct crypto_ec_point *b,
1547 struct crypto_ec_point *c)
1548 {
1549 mp_int mu;
1550 ecc_point *ta = NULL, *tb = NULL;
1551 ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1552 mp_int *modulus = &e->prime;
1553 int ret;
1554
1555 if (TEST_FAIL())
1556 return -1;
1557
1558 ret = mp_init(&mu);
1559 if (ret != MP_OKAY)
1560 return -1;
1561
1562 ret = mp_montgomery_calc_normalization(&mu, modulus);
1563 if (ret != MP_OKAY) {
1564 mp_clear(&mu);
1565 return -1;
1566 }
1567
1568 if (!mp_isone(&mu)) {
1569 ta = wc_ecc_new_point();
1570 if (!ta) {
1571 mp_clear(&mu);
1572 return -1;
1573 }
1574 tb = wc_ecc_new_point();
1575 if (!tb) {
1576 wc_ecc_del_point(ta);
1577 mp_clear(&mu);
1578 return -1;
1579 }
1580
1581 if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1582 mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1583 mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1584 mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1585 mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1586 mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1587 ret = -1;
1588 goto end;
1589 }
1590 pa = ta;
1591 pb = tb;
1592 }
1593
1594 ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1595 &e->prime, e->mont_b);
1596 if (ret != 0) {
1597 ret = -1;
1598 goto end;
1599 }
1600
1601 if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1602 ret = -1;
1603 else
1604 ret = 0;
1605 end:
1606 wc_ecc_del_point(tb);
1607 wc_ecc_del_point(ta);
1608 mp_clear(&mu);
1609 return ret;
1610 }
1611
1612
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)1613 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1614 const struct crypto_bignum *b,
1615 struct crypto_ec_point *res)
1616 {
1617 int ret;
1618
1619 if (TEST_FAIL())
1620 return -1;
1621
1622 ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
1623 &e->a, &e->prime, 1);
1624 return ret == 0 ? 0 : -1;
1625 }
1626
1627
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)1628 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1629 {
1630 ecc_point *point = (ecc_point *) p;
1631
1632 if (TEST_FAIL())
1633 return -1;
1634
1635 if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
1636 return -1;
1637
1638 return 0;
1639 }
1640
1641
1642 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)1643 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1644 const struct crypto_bignum *x)
1645 {
1646 mp_int *y2 = NULL;
1647 mp_int t;
1648 int calced = 0;
1649
1650 if (TEST_FAIL())
1651 return NULL;
1652
1653 if (mp_init(&t) != MP_OKAY)
1654 return NULL;
1655
1656 y2 = (mp_int *) crypto_bignum_init();
1657 if (!y2)
1658 goto done;
1659
1660 if (mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
1661 mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
1662 mp_mulmod((mp_int *) x, &e->a, &e->prime, &t) != 0 ||
1663 mp_addmod(y2, &t, &e->prime, y2) != 0 ||
1664 mp_addmod(y2, &e->b, &e->prime, y2) != 0)
1665 goto done;
1666
1667 calced = 1;
1668 done:
1669 if (!calced) {
1670 if (y2) {
1671 mp_clear(y2);
1672 os_free(y2);
1673 }
1674 mp_clear(&t);
1675 }
1676
1677 return (struct crypto_bignum *) y2;
1678 }
1679
1680
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)1681 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1682 const struct crypto_ec_point *p)
1683 {
1684 return wc_ecc_point_is_at_infinity((ecc_point *) p);
1685 }
1686
1687
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)1688 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1689 const struct crypto_ec_point *p)
1690 {
1691 return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
1692 MP_OKAY;
1693 }
1694
1695
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)1696 int crypto_ec_point_cmp(const struct crypto_ec *e,
1697 const struct crypto_ec_point *a,
1698 const struct crypto_ec_point *b)
1699 {
1700 return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
1701 }
1702
1703
1704 struct crypto_ecdh {
1705 struct crypto_ec *ec;
1706 };
1707
crypto_ecdh_init(int group)1708 struct crypto_ecdh * crypto_ecdh_init(int group)
1709 {
1710 struct crypto_ecdh *ecdh = NULL;
1711 WC_RNG rng;
1712 int ret;
1713
1714 if (wc_InitRng(&rng) != 0)
1715 goto fail;
1716
1717 ecdh = os_zalloc(sizeof(*ecdh));
1718 if (!ecdh)
1719 goto fail;
1720
1721 ecdh->ec = crypto_ec_init(group);
1722 if (!ecdh->ec)
1723 goto fail;
1724
1725 ret = wc_ecc_make_key_ex(&rng, ecdh->ec->key.dp->size, &ecdh->ec->key,
1726 ecdh->ec->key.dp->id);
1727 if (ret < 0)
1728 goto fail;
1729
1730 done:
1731 wc_FreeRng(&rng);
1732
1733 return ecdh;
1734 fail:
1735 crypto_ecdh_deinit(ecdh);
1736 ecdh = NULL;
1737 goto done;
1738 }
1739
1740
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)1741 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
1742 {
1743 if (ecdh) {
1744 crypto_ec_deinit(ecdh->ec);
1745 os_free(ecdh);
1746 }
1747 }
1748
1749
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)1750 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
1751 {
1752 struct wpabuf *buf = NULL;
1753 int ret;
1754 int len = ecdh->ec->key.dp->size;
1755
1756 buf = wpabuf_alloc(inc_y ? 2 * len : len);
1757 if (!buf)
1758 goto fail;
1759
1760 ret = crypto_bignum_to_bin((struct crypto_bignum *)
1761 ecdh->ec->key.pubkey.x, wpabuf_put(buf, len),
1762 len, len);
1763 if (ret < 0)
1764 goto fail;
1765 if (inc_y) {
1766 ret = crypto_bignum_to_bin((struct crypto_bignum *)
1767 ecdh->ec->key.pubkey.y,
1768 wpabuf_put(buf, len), len, len);
1769 if (ret < 0)
1770 goto fail;
1771 }
1772
1773 done:
1774 return buf;
1775 fail:
1776 wpabuf_free(buf);
1777 buf = NULL;
1778 goto done;
1779 }
1780
1781
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)1782 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
1783 const u8 *key, size_t len)
1784 {
1785 int ret;
1786 struct wpabuf *pubkey = NULL;
1787 struct wpabuf *secret = NULL;
1788 word32 key_len = ecdh->ec->key.dp->size;
1789 ecc_point *point = NULL;
1790 size_t need_key_len = inc_y ? 2 * key_len : key_len;
1791
1792 if (len < need_key_len)
1793 goto fail;
1794 pubkey = wpabuf_alloc(1 + 2 * key_len);
1795 if (!pubkey)
1796 goto fail;
1797 wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
1798 wpabuf_put_data(pubkey, key, need_key_len);
1799
1800 point = wc_ecc_new_point();
1801 if (!point)
1802 goto fail;
1803
1804 ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
1805 ecdh->ec->key.idx, point);
1806 if (ret != MP_OKAY)
1807 goto fail;
1808
1809 secret = wpabuf_alloc(key_len);
1810 if (!secret)
1811 goto fail;
1812
1813 ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point,
1814 wpabuf_put(secret, key_len), &key_len);
1815 if (ret != MP_OKAY)
1816 goto fail;
1817
1818 done:
1819 wc_ecc_del_point(point);
1820 wpabuf_free(pubkey);
1821 return secret;
1822 fail:
1823 wpabuf_free(secret);
1824 secret = NULL;
1825 goto done;
1826 }
1827
1828
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)1829 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
1830 {
1831 return crypto_ec_prime_len(ecdh->ec);
1832 }
1833
1834 #endif /* CONFIG_ECC */
1835