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