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