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 #include "tls/asn1.h"
14
15 /* wolfSSL headers */
16 #include <wolfssl/options.h> /* options.h needs to be included first */
17 #include <wolfssl/version.h>
18 #include <wolfssl/openssl/bn.h>
19 #include <wolfssl/wolfcrypt/aes.h>
20 #include <wolfssl/wolfcrypt/arc4.h>
21 #include <wolfssl/wolfcrypt/asn_public.h>
22 #include <wolfssl/wolfcrypt/cmac.h>
23 #include <wolfssl/wolfcrypt/des3.h>
24 #include <wolfssl/wolfcrypt/dh.h>
25 #include <wolfssl/wolfcrypt/ecc.h>
26 #include <wolfssl/wolfcrypt/error-crypt.h>
27 #include <wolfssl/wolfcrypt/hmac.h>
28 #include <wolfssl/wolfcrypt/md4.h>
29 #include <wolfssl/wolfcrypt/md5.h>
30 #include <wolfssl/wolfcrypt/pkcs7.h>
31 #include <wolfssl/wolfcrypt/pwdbased.h>
32 #include <wolfssl/wolfcrypt/sha.h>
33 #include <wolfssl/wolfcrypt/sha256.h>
34 #include <wolfssl/wolfcrypt/sha512.h>
35
36 #ifdef CONFIG_FIPS
37 #ifndef HAVE_FIPS
38 #warning "You are compiling wpa_supplicant/hostapd in FIPS mode but wolfSSL is not configured for FIPS mode."
39 #endif /* HAVE_FIPS */
40 #endif /* CONFIG_FIPS */
41
42
43 #ifdef CONFIG_FIPS
44 #if !defined(HAVE_FIPS_VERSION) || HAVE_FIPS_VERSION <= 2
45 #define WOLFSSL_OLD_FIPS
46 #endif
47 #endif
48
49 #if LIBWOLFSSL_VERSION_HEX < 0x05004000
wc_EccPublicKeyToDer_ex(ecc_key * key,byte * output,word32 inLen,int with_AlgCurve,int comp)50 static int wc_EccPublicKeyToDer_ex(ecc_key *key, byte *output,
51 word32 inLen, int with_AlgCurve,
52 int comp)
53 {
54 return wc_EccPublicKeyToDer(key, output, inLen, with_AlgCurve);
55 }
56 #endif /* version < 5.4.0 */
57
58 #define LOG_WOLF_ERROR_VA(msg, ...) \
59 wpa_printf(MSG_ERROR, "wolfSSL: %s:%d " msg, \
60 __func__, __LINE__, __VA_ARGS__)
61
62 #define LOG_WOLF_ERROR(msg) \
63 LOG_WOLF_ERROR_VA("%s", (msg))
64
65 #define LOG_WOLF_ERROR_FUNC(func, err) \
66 LOG_WOLF_ERROR_VA(#func " failed with err: %d %s", \
67 (err), wc_GetErrorString(err))
68
69 #define LOG_WOLF_ERROR_FUNC_NULL(func) \
70 LOG_WOLF_ERROR(#func " failed with NULL return")
71
72 #define LOG_INVALID_PARAMETERS() \
73 LOG_WOLF_ERROR("invalid input parameters")
74
75
76 /* Helper functions to make type allocation uniform */
77
wc_rng_init(void)78 static WC_RNG * wc_rng_init(void)
79 {
80 WC_RNG *ret;
81
82 #ifdef CONFIG_FIPS
83 ret = os_zalloc(sizeof(WC_RNG));
84 if (!ret) {
85 LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
86 } else {
87 int err;
88
89 err = wc_InitRng(ret);
90 if (err != 0) {
91 LOG_WOLF_ERROR_FUNC(wc_InitRng, err);
92 os_free(ret);
93 ret = NULL;
94 }
95 }
96 #else /* CONFIG_FIPS */
97 ret = wc_rng_new(NULL, 0, NULL);
98 if (!ret)
99 LOG_WOLF_ERROR_FUNC_NULL(wc_rng_new);
100 #endif /* CONFIG_FIPS */
101
102 return ret;
103 }
104
105
wc_rng_deinit(WC_RNG * rng)106 static void wc_rng_deinit(WC_RNG *rng)
107 {
108 #ifdef CONFIG_FIPS
109 wc_FreeRng(rng);
110 os_free(rng);
111 #else /* CONFIG_FIPS */
112 wc_rng_free(rng);
113 #endif /* CONFIG_FIPS */
114 }
115
116
ecc_key_init(void)117 static ecc_key * ecc_key_init(void)
118 {
119 ecc_key *ret;
120 #ifdef CONFIG_FIPS
121 int err;
122
123 ret = os_zalloc(sizeof(ecc_key));
124 if (!ret) {
125 LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
126 } else {
127 err = wc_ecc_init_ex(ret, NULL, INVALID_DEVID);
128 if (err != 0) {
129 LOG_WOLF_ERROR("wc_ecc_init_ex failed");
130 os_free(ret);
131 ret = NULL;
132 }
133 }
134 #else /* CONFIG_FIPS */
135 ret = wc_ecc_key_new(NULL);
136 if (!ret)
137 LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_key_new);
138 #endif /* CONFIG_FIPS */
139
140 return ret;
141 }
142
143
ecc_key_deinit(ecc_key * key)144 static void ecc_key_deinit(ecc_key *key)
145 {
146 #ifdef CONFIG_FIPS
147 wc_ecc_free(key);
148 os_free(key);
149 #else /* CONFIG_FIPS */
150 wc_ecc_key_free(key);
151 #endif /* CONFIG_FIPS */
152 }
153
154 /* end of helper functions */
155
156
157 #ifndef CONFIG_FIPS
158
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)159 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
160 {
161 Md4 md4;
162 size_t i;
163
164 if (TEST_FAIL())
165 return -1;
166
167 wc_InitMd4(&md4);
168
169 for (i = 0; i < num_elem; i++)
170 wc_Md4Update(&md4, addr[i], len[i]);
171
172 wc_Md4Final(&md4, mac);
173
174 return 0;
175 }
176
177
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)178 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
179 {
180 wc_Md5 md5;
181 size_t i;
182 int err;
183 int ret = -1;
184
185 if (TEST_FAIL())
186 return -1;
187
188 err = wc_InitMd5(&md5);
189 if (err != 0) {
190 LOG_WOLF_ERROR_FUNC(wc_InitMd5, err);
191 return -1;
192 }
193
194 for (i = 0; i < num_elem; i++) {
195 err = wc_Md5Update(&md5, addr[i], len[i]);
196 if (err != 0) {
197 LOG_WOLF_ERROR_FUNC(wc_Md5Update, err);
198 goto fail;
199 }
200 }
201
202 err = wc_Md5Final(&md5, mac);
203 if (err != 0) {
204 LOG_WOLF_ERROR_FUNC(wc_Md5Final, err);
205 goto fail;
206 }
207
208 ret = 0;
209 fail:
210 wc_Md5Free(&md5);
211 return ret;
212 }
213
214 #endif /* CONFIG_FIPS */
215
216
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)217 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
218 {
219 wc_Sha sha;
220 size_t i;
221 int err;
222 int ret = -1;
223
224 if (TEST_FAIL())
225 return -1;
226
227 err = wc_InitSha(&sha);
228 if (err != 0) {
229 LOG_WOLF_ERROR_FUNC(wc_InitSha, err);
230 return -1;
231 }
232
233 for (i = 0; i < num_elem; i++) {
234 err = wc_ShaUpdate(&sha, addr[i], len[i]);
235 if (err != 0) {
236 LOG_WOLF_ERROR_FUNC(wc_ShaUpdate, err);
237 goto fail;
238 }
239 }
240
241 err = wc_ShaFinal(&sha, mac);
242 if (err != 0) {
243 LOG_WOLF_ERROR_FUNC(wc_ShaFinal, err);
244 goto fail;
245 }
246
247 ret = 0;
248 fail:
249 wc_ShaFree(&sha);
250 return ret;
251 }
252
253
254 #ifndef NO_SHA256_WRAPPER
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)255 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
256 u8 *mac)
257 {
258 wc_Sha256 sha256;
259 size_t i;
260 int err;
261 int ret = -1;
262
263 if (TEST_FAIL())
264 return -1;
265
266 err = wc_InitSha256(&sha256);
267 if (err != 0) {
268 LOG_WOLF_ERROR_FUNC(wc_InitSha256, err);
269 return -1;
270 }
271
272 for (i = 0; i < num_elem; i++) {
273 err = wc_Sha256Update(&sha256, addr[i], len[i]);
274 if (err != 0) {
275 LOG_WOLF_ERROR_FUNC(wc_Sha256Update, err);
276 goto fail;
277 }
278 }
279
280 err = wc_Sha256Final(&sha256, mac);
281 if (err != 0) {
282 LOG_WOLF_ERROR_FUNC(wc_Sha256Final, err);
283 goto fail;
284 }
285
286 ret = 0;
287 fail:
288 wc_Sha256Free(&sha256);
289 return ret;
290 }
291 #endif /* NO_SHA256_WRAPPER */
292
293
294 #ifdef CONFIG_SHA384
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)295 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
296 u8 *mac)
297 {
298 wc_Sha384 sha384;
299 size_t i;
300 int err;
301 int ret = -1;
302
303 if (TEST_FAIL())
304 return -1;
305
306 err = wc_InitSha384(&sha384);
307 if (err != 0) {
308 LOG_WOLF_ERROR_FUNC(wc_InitSha384, err);
309 return -1;
310 }
311
312 for (i = 0; i < num_elem; i++) {
313 err = wc_Sha384Update(&sha384, addr[i], len[i]);
314 if (err != 0) {
315 LOG_WOLF_ERROR_FUNC(wc_Sha384Update, err);
316 goto fail;
317 }
318 }
319
320 err = wc_Sha384Final(&sha384, mac);
321 if (err != 0) {
322 LOG_WOLF_ERROR_FUNC(wc_Sha384Final, err);
323 goto fail;
324 }
325
326 ret = 0;
327 fail:
328 wc_Sha384Free(&sha384);
329 return ret;
330 }
331 #endif /* CONFIG_SHA384 */
332
333
334 #ifdef CONFIG_SHA512
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)335 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
336 u8 *mac)
337 {
338 wc_Sha512 sha512;
339 size_t i;
340 int err;
341 int ret = -1;
342
343 if (TEST_FAIL())
344 return -1;
345
346 err = wc_InitSha512(&sha512);
347 if (err != 0) {
348 LOG_WOLF_ERROR_FUNC(wc_InitSha512, err);
349 return -1;
350 }
351
352 for (i = 0; i < num_elem; i++) {
353 err = wc_Sha512Update(&sha512, addr[i], len[i]);
354 if (err != 0) {
355 LOG_WOLF_ERROR_FUNC(wc_Sha512Update, err);
356 goto fail;
357 }
358 }
359
360 err = wc_Sha512Final(&sha512, mac);
361 if (err != 0) {
362 LOG_WOLF_ERROR_FUNC(wc_Sha512Final, err);
363 goto fail;
364 }
365
366 ret = 0;
367 fail:
368 wc_Sha512Free(&sha512);
369 return ret;
370 }
371 #endif /* CONFIG_SHA512 */
372
373
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)374 static int wolfssl_hmac_vector(int type, const u8 *key,
375 size_t key_len, size_t num_elem,
376 const u8 *addr[], const size_t *len, u8 *mac,
377 unsigned int mdlen)
378 {
379 Hmac hmac;
380 size_t i;
381 int err;
382 int ret = -1;
383
384 (void) mdlen;
385
386 if (TEST_FAIL())
387 return -1;
388
389 err = wc_HmacInit(&hmac, NULL, INVALID_DEVID);
390 if (err != 0) {
391 LOG_WOLF_ERROR_FUNC(wc_HmacInit, err);
392 return -1;
393 }
394
395 err = wc_HmacSetKey(&hmac, type, key, (word32) key_len);
396 if (err != 0) {
397 LOG_WOLF_ERROR_FUNC(wc_HmacSetKey, err);
398 goto fail;
399 }
400
401 for (i = 0; i < num_elem; i++) {
402 err = wc_HmacUpdate(&hmac, addr[i], len[i]);
403 if (err != 0) {
404 LOG_WOLF_ERROR_FUNC(wc_HmacUpdate, err);
405 goto fail;
406 }
407 }
408 err = wc_HmacFinal(&hmac, mac);
409 if (err != 0) {
410 LOG_WOLF_ERROR_FUNC(wc_HmacFinal, err);
411 goto fail;
412 }
413
414 ret = 0;
415 fail:
416 wc_HmacFree(&hmac);
417 return ret;
418 }
419
420
421 #ifndef CONFIG_FIPS
422
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)423 int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
424 const u8 *addr[], const size_t *len, u8 *mac)
425 {
426 return wolfssl_hmac_vector(WC_MD5, key, key_len, num_elem, addr, len,
427 mac, 16);
428 }
429
430
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)431 int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
432 u8 *mac)
433 {
434 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
435 }
436
437 #endif /* CONFIG_FIPS */
438
439
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)440 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
441 const u8 *addr[], const size_t *len, u8 *mac)
442 {
443 return wolfssl_hmac_vector(WC_SHA, key, key_len, num_elem, addr, len,
444 mac, 20);
445 }
446
447
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)448 int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
449 u8 *mac)
450 {
451 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
452 }
453
454
455 #ifdef CONFIG_SHA256
456
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)457 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
458 const u8 *addr[], const size_t *len, u8 *mac)
459 {
460 return wolfssl_hmac_vector(WC_SHA256, key, key_len, num_elem, addr, len,
461 mac, 32);
462 }
463
464
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)465 int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
466 size_t data_len, u8 *mac)
467 {
468 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
469 }
470
471 #endif /* CONFIG_SHA256 */
472
473
474 #ifdef CONFIG_SHA384
475
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)476 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
477 const u8 *addr[], const size_t *len, u8 *mac)
478 {
479 return wolfssl_hmac_vector(WC_SHA384, key, key_len, num_elem, addr, len,
480 mac, 48);
481 }
482
483
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)484 int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
485 size_t data_len, u8 *mac)
486 {
487 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
488 }
489
490 #endif /* CONFIG_SHA384 */
491
492
493 #ifdef CONFIG_SHA512
494
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)495 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
496 const u8 *addr[], const size_t *len, u8 *mac)
497 {
498 return wolfssl_hmac_vector(WC_SHA512, key, key_len, num_elem, addr, len,
499 mac, 64);
500 }
501
502
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)503 int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
504 size_t data_len, u8 *mac)
505 {
506 return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
507 }
508
509 #endif /* CONFIG_SHA512 */
510
511
pbkdf2_sha1(const char * passphrase,const u8 * ssid,size_t ssid_len,int iterations,u8 * buf,size_t buflen)512 int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
513 int iterations, u8 *buf, size_t buflen)
514 {
515 int ret;
516
517 ret = wc_PBKDF2(buf, (const byte *) passphrase, os_strlen(passphrase),
518 ssid, ssid_len, iterations, buflen, WC_SHA);
519 if (ret != 0) {
520 if (ret == HMAC_MIN_KEYLEN_E) {
521 LOG_WOLF_ERROR_VA("wolfSSL: Password is too short. Make sure your password is at least %d characters long. This is a requirement for FIPS builds.",
522 HMAC_FIPS_MIN_KEY);
523 }
524 return -1;
525 }
526 return 0;
527 }
528
529
530 #ifdef CONFIG_DES
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)531 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
532 {
533 Des des;
534 u8 pkey[8], next, tmp;
535 int i;
536
537 /* Add parity bits to the key */
538 next = 0;
539 for (i = 0; i < 7; i++) {
540 tmp = key[i];
541 pkey[i] = (tmp >> i) | next | 1;
542 next = tmp << (7 - i);
543 }
544 pkey[i] = next | 1;
545
546 wc_Des_SetKey(&des, pkey, NULL, DES_ENCRYPTION);
547 wc_Des_EcbEncrypt(&des, cypher, clear, DES_BLOCK_SIZE);
548
549 return 0;
550 }
551 #endif /* CONFIG_DES */
552
553
aes_encrypt_init(const u8 * key,size_t len)554 void * aes_encrypt_init(const u8 *key, size_t len)
555 {
556 Aes *aes;
557 int err;
558
559 if (TEST_FAIL())
560 return NULL;
561
562 aes = os_malloc(sizeof(Aes));
563 if (!aes) {
564 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
565 return NULL;
566 }
567
568 err = wc_AesSetKey(aes, key, len, NULL, AES_ENCRYPTION);
569 if (err < 0) {
570 LOG_WOLF_ERROR_FUNC(wc_AesSetKey, err);
571 os_free(aes);
572 return NULL;
573 }
574
575 return aes;
576 }
577
578
aes_encrypt(void * ctx,const u8 * plain,u8 * crypt)579 int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
580 {
581 #if defined(HAVE_FIPS) && \
582 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION <= 2))
583 /* Old FIPS has void return on this API */
584 wc_AesEncryptDirect(ctx, crypt, plain);
585 #else
586 int err = wc_AesEncryptDirect(ctx, crypt, plain);
587
588 if (err != 0) {
589 LOG_WOLF_ERROR_FUNC(wc_AesEncryptDirect, err);
590 return -1;
591 }
592 #endif
593 return 0;
594 }
595
596
aes_encrypt_deinit(void * ctx)597 void aes_encrypt_deinit(void *ctx)
598 {
599 os_free(ctx);
600 }
601
602
aes_decrypt_init(const u8 * key,size_t len)603 void * aes_decrypt_init(const u8 *key, size_t len)
604 {
605 Aes *aes;
606 int err;
607
608 if (TEST_FAIL())
609 return NULL;
610
611 aes = os_malloc(sizeof(Aes));
612 if (!aes) {
613 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
614 return NULL;
615 }
616
617 err = wc_AesSetKey(aes, key, len, NULL, AES_DECRYPTION);
618 if (err < 0) {
619 LOG_WOLF_ERROR_FUNC(wc_AesSetKey, err);
620 os_free(aes);
621 return NULL;
622 }
623
624 return aes;
625 }
626
627
aes_decrypt(void * ctx,const u8 * crypt,u8 * plain)628 int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
629 {
630 #if defined(HAVE_FIPS) && \
631 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION <= 2))
632 /* Old FIPS has void return on this API */
633 wc_AesDecryptDirect(ctx, plain, crypt);
634 #else
635 int err = wc_AesDecryptDirect(ctx, plain, crypt);
636
637 if (err != 0) {
638 LOG_WOLF_ERROR_FUNC(wc_AesDecryptDirect, err);
639 return -1;
640 }
641 #endif
642 return 0;
643 }
644
645
aes_decrypt_deinit(void * ctx)646 void aes_decrypt_deinit(void *ctx)
647 {
648 os_free(ctx);
649 }
650
651
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)652 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
653 {
654 Aes aes;
655 int ret;
656
657 if (TEST_FAIL())
658 return -1;
659
660 ret = wc_AesSetKey(&aes, key, 16, iv, AES_ENCRYPTION);
661 if (ret != 0)
662 return -1;
663
664 ret = wc_AesCbcEncrypt(&aes, data, data, data_len);
665 if (ret != 0)
666 return -1;
667 return 0;
668 }
669
670
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)671 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
672 {
673 Aes aes;
674 int ret;
675
676 if (TEST_FAIL())
677 return -1;
678
679 ret = wc_AesSetKey(&aes, key, 16, iv, AES_DECRYPTION);
680 if (ret != 0)
681 return -1;
682
683 ret = wc_AesCbcDecrypt(&aes, data, data, data_len);
684 if (ret != 0)
685 return -1;
686 return 0;
687 }
688
689
690 #ifndef CONFIG_FIPS
691 #ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP
aes_wrap(const u8 * kek,size_t kek_len,int n,const u8 * plain,u8 * cipher)692 int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
693 {
694 #ifdef HAVE_AES_KEYWRAP
695 int ret;
696
697 if (TEST_FAIL())
698 return -1;
699
700 ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8,
701 NULL);
702 return ret != (n + 1) * 8 ? -1 : 0;
703 #else /* HAVE_AES_KEYWRAP */
704 return -1;
705 #endif /* HAVE_AES_KEYWRAP */
706 }
707
708
aes_unwrap(const u8 * kek,size_t kek_len,int n,const u8 * cipher,u8 * plain)709 int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
710 u8 *plain)
711 {
712 #ifdef HAVE_AES_KEYWRAP
713 int ret;
714
715 if (TEST_FAIL())
716 return -1;
717
718 ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8,
719 NULL);
720 return ret != n * 8 ? -1 : 0;
721 #else /* HAVE_AES_KEYWRAP */
722 return -1;
723 #endif /* HAVE_AES_KEYWRAP */
724 }
725 #endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */
726 #endif /* CONFIG_FIPS */
727
728
729 #ifndef CONFIG_NO_RC4
rc4_skip(const u8 * key,size_t keylen,size_t skip,u8 * data,size_t data_len)730 int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data,
731 size_t data_len)
732 {
733 #ifndef NO_RC4
734 Arc4 arc4;
735 unsigned char skip_buf[16];
736
737 wc_Arc4SetKey(&arc4, key, keylen);
738
739 while (skip >= sizeof(skip_buf)) {
740 size_t len = skip;
741
742 if (len > sizeof(skip_buf))
743 len = sizeof(skip_buf);
744 wc_Arc4Process(&arc4, skip_buf, skip_buf, len);
745 skip -= len;
746 }
747
748 wc_Arc4Process(&arc4, data, data, data_len);
749
750 return 0;
751 #else /* NO_RC4 */
752 return -1;
753 #endif /* NO_RC4 */
754 }
755 #endif /* CONFIG_NO_RC4 */
756
757
758 #if defined(EAP_IKEV2) || defined(EAP_IKEV2_DYNAMIC) \
759 || defined(EAP_SERVER_IKEV2)
760 union wolfssl_cipher {
761 Aes aes;
762 Des3 des3;
763 Arc4 arc4;
764 };
765
766 struct crypto_cipher {
767 enum crypto_cipher_alg alg;
768 union wolfssl_cipher enc;
769 union wolfssl_cipher dec;
770 };
771
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)772 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
773 const u8 *iv, const u8 *key,
774 size_t key_len)
775 {
776 struct crypto_cipher *ctx;
777
778 ctx = os_zalloc(sizeof(*ctx));
779 if (!ctx)
780 return NULL;
781
782 switch (alg) {
783 #ifndef CONFIG_NO_RC4
784 #ifndef NO_RC4
785 case CRYPTO_CIPHER_ALG_RC4:
786 wc_Arc4SetKey(&ctx->enc.arc4, key, key_len);
787 wc_Arc4SetKey(&ctx->dec.arc4, key, key_len);
788 break;
789 #endif /* NO_RC4 */
790 #endif /* CONFIG_NO_RC4 */
791 #ifndef NO_AES
792 case CRYPTO_CIPHER_ALG_AES:
793 switch (key_len) {
794 case 16:
795 case 24:
796 case 32:
797 break;
798 default:
799 os_free(ctx);
800 return NULL;
801 }
802 if (wc_AesSetKey(&ctx->enc.aes, key, key_len, iv,
803 AES_ENCRYPTION) ||
804 wc_AesSetKey(&ctx->dec.aes, key, key_len, iv,
805 AES_DECRYPTION)) {
806 os_free(ctx);
807 return NULL;
808 }
809 break;
810 #endif /* NO_AES */
811 #ifndef NO_DES3
812 case CRYPTO_CIPHER_ALG_3DES:
813 if (key_len != DES3_KEYLEN ||
814 wc_Des3_SetKey(&ctx->enc.des3, key, iv, DES_ENCRYPTION) ||
815 wc_Des3_SetKey(&ctx->dec.des3, key, iv, DES_DECRYPTION)) {
816 os_free(ctx);
817 return NULL;
818 }
819 break;
820 #endif /* NO_DES3 */
821 case CRYPTO_CIPHER_ALG_RC2:
822 case CRYPTO_CIPHER_ALG_DES:
823 default:
824 os_free(ctx);
825 return NULL;
826 }
827
828 ctx->alg = alg;
829
830 return ctx;
831 }
832
833
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)834 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
835 u8 *crypt, size_t len)
836 {
837 switch (ctx->alg) {
838 #ifndef CONFIG_NO_RC4
839 #ifndef NO_RC4
840 case CRYPTO_CIPHER_ALG_RC4:
841 wc_Arc4Process(&ctx->enc.arc4, crypt, plain, len);
842 return 0;
843 #endif /* NO_RC4 */
844 #endif /* CONFIG_NO_RC4 */
845 #ifndef NO_AES
846 case CRYPTO_CIPHER_ALG_AES:
847 if (wc_AesCbcEncrypt(&ctx->enc.aes, crypt, plain, len) != 0)
848 return -1;
849 return 0;
850 #endif /* NO_AES */
851 #ifndef NO_DES3
852 case CRYPTO_CIPHER_ALG_3DES:
853 if (wc_Des3_CbcEncrypt(&ctx->enc.des3, crypt, plain, len) != 0)
854 return -1;
855 return 0;
856 #endif /* NO_DES3 */
857 default:
858 return -1;
859 }
860 return -1;
861 }
862
863
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)864 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
865 u8 *plain, size_t len)
866 {
867 switch (ctx->alg) {
868 #ifndef CONFIG_NO_RC4
869 #ifndef NO_RC4
870 case CRYPTO_CIPHER_ALG_RC4:
871 wc_Arc4Process(&ctx->dec.arc4, plain, crypt, len);
872 return 0;
873 #endif /* NO_RC4 */
874 #endif /* CONFIG_NO_RC4 */
875 #ifndef NO_AES
876 case CRYPTO_CIPHER_ALG_AES:
877 if (wc_AesCbcDecrypt(&ctx->dec.aes, plain, crypt, len) != 0)
878 return -1;
879 return 0;
880 #endif /* NO_AES */
881 #ifndef NO_DES3
882 case CRYPTO_CIPHER_ALG_3DES:
883 if (wc_Des3_CbcDecrypt(&ctx->dec.des3, plain, crypt, len) != 0)
884 return -1;
885 return 0;
886 #endif /* NO_DES3 */
887 default:
888 return -1;
889 }
890 return -1;
891 }
892
893
crypto_cipher_deinit(struct crypto_cipher * ctx)894 void crypto_cipher_deinit(struct crypto_cipher *ctx)
895 {
896 os_free(ctx);
897 }
898
899 #endif
900
901
902 #ifdef CONFIG_WPS
903
904 static const unsigned char RFC3526_PRIME_1536[] = {
905 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
906 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
907 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
908 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
909 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
910 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
911 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
912 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
913 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
914 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
915 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
916 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
917 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
918 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
919 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
920 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
921 };
922
923 static const unsigned char RFC3526_GENERATOR_1536[] = {
924 0x02
925 };
926
927 #define RFC3526_LEN sizeof(RFC3526_PRIME_1536)
928
929
dh5_init(struct wpabuf ** priv,struct wpabuf ** publ)930 void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
931 {
932 WC_RNG rng;
933 DhKey *ret = NULL;
934 DhKey *dh = NULL;
935 struct wpabuf *privkey = NULL;
936 struct wpabuf *pubkey = NULL;
937 word32 priv_sz, pub_sz;
938
939 *priv = NULL;
940 wpabuf_free(*publ);
941 *publ = NULL;
942
943 dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
944 if (!dh)
945 return NULL;
946 wc_InitDhKey(dh);
947
948 if (wc_InitRng(&rng) != 0) {
949 XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
950 return NULL;
951 }
952
953 privkey = wpabuf_alloc(RFC3526_LEN);
954 pubkey = wpabuf_alloc(RFC3526_LEN);
955 if (!privkey || !pubkey)
956 goto done;
957
958 if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
959 RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
960 != 0)
961 goto done;
962
963 priv_sz = pub_sz = RFC3526_LEN;
964 if (wc_DhGenerateKeyPair(dh, &rng, wpabuf_mhead(privkey), &priv_sz,
965 wpabuf_mhead(pubkey), &pub_sz) != 0)
966 goto done;
967
968 wpabuf_put(privkey, priv_sz);
969 wpabuf_put(pubkey, pub_sz);
970
971 ret = dh;
972 *priv = privkey;
973 *publ = pubkey;
974 dh = NULL;
975 privkey = NULL;
976 pubkey = NULL;
977 done:
978 wpabuf_clear_free(pubkey);
979 wpabuf_clear_free(privkey);
980 if (dh) {
981 wc_FreeDhKey(dh);
982 XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
983 }
984 wc_FreeRng(&rng);
985 return ret;
986 }
987
988
989 #ifdef CONFIG_WPS_NFC
990
dh5_init_fixed(const struct wpabuf * priv,const struct wpabuf * publ)991 void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
992 {
993 DhKey *ret = NULL;
994 DhKey *dh;
995 byte *secret;
996 word32 secret_sz;
997
998 dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
999 if (!dh)
1000 return NULL;
1001 wc_InitDhKey(dh);
1002
1003 secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1004 if (!secret)
1005 goto done;
1006
1007 if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536),
1008 RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536))
1009 != 0)
1010 goto done;
1011
1012 if (wc_DhAgree(dh, secret, &secret_sz, wpabuf_head(priv),
1013 wpabuf_len(priv), RFC3526_GENERATOR_1536,
1014 sizeof(RFC3526_GENERATOR_1536)) != 0)
1015 goto done;
1016
1017 if (secret_sz != wpabuf_len(publ) ||
1018 os_memcmp(secret, wpabuf_head(publ), secret_sz) != 0)
1019 goto done;
1020
1021 ret = dh;
1022 dh = NULL;
1023 done:
1024 if (dh) {
1025 wc_FreeDhKey(dh);
1026 XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1027 }
1028 XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1029 return ret;
1030 }
1031
1032 #endif /* CONFIG_WPS_NFC */
1033
1034
dh5_derive_shared(void * ctx,const struct wpabuf * peer_public,const struct wpabuf * own_private)1035 struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
1036 const struct wpabuf *own_private)
1037 {
1038 struct wpabuf *ret = NULL;
1039 struct wpabuf *secret;
1040 word32 secret_sz;
1041
1042 secret = wpabuf_alloc(RFC3526_LEN);
1043 if (!secret)
1044 goto done;
1045
1046 if (wc_DhAgree(ctx, wpabuf_mhead(secret), &secret_sz,
1047 wpabuf_head(own_private), wpabuf_len(own_private),
1048 wpabuf_head(peer_public), wpabuf_len(peer_public)) != 0)
1049 goto done;
1050
1051 wpabuf_put(secret, secret_sz);
1052
1053 ret = secret;
1054 secret = NULL;
1055 done:
1056 wpabuf_clear_free(secret);
1057 return ret;
1058 }
1059
1060
dh5_free(void * ctx)1061 void dh5_free(void *ctx)
1062 {
1063 if (!ctx)
1064 return;
1065
1066 wc_FreeDhKey(ctx);
1067 XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1068 }
1069
1070 #endif /* CONFIG_WPS */
1071
1072
crypto_dh_init(u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)1073 int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
1074 u8 *pubkey)
1075 {
1076 int ret = -1;
1077 WC_RNG rng;
1078 DhKey *dh = NULL;
1079 word32 priv_sz, pub_sz;
1080
1081 if (TEST_FAIL())
1082 return -1;
1083
1084 dh = os_malloc(sizeof(DhKey));
1085 if (!dh)
1086 return -1;
1087 wc_InitDhKey(dh);
1088
1089 if (wc_InitRng(&rng) != 0) {
1090 os_free(dh);
1091 return -1;
1092 }
1093
1094 if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
1095 goto done;
1096
1097 priv_sz = pub_sz = prime_len;
1098 if (wc_DhGenerateKeyPair(dh, &rng, privkey, &priv_sz, pubkey, &pub_sz)
1099 != 0)
1100 goto done;
1101
1102 if (priv_sz < prime_len) {
1103 size_t pad_sz = prime_len - priv_sz;
1104
1105 os_memmove(privkey + pad_sz, privkey, priv_sz);
1106 os_memset(privkey, 0, pad_sz);
1107 }
1108
1109 if (pub_sz < prime_len) {
1110 size_t pad_sz = prime_len - pub_sz;
1111
1112 os_memmove(pubkey + pad_sz, pubkey, pub_sz);
1113 os_memset(pubkey, 0, pad_sz);
1114 }
1115 ret = 0;
1116 done:
1117 wc_FreeDhKey(dh);
1118 os_free(dh);
1119 wc_FreeRng(&rng);
1120 return ret;
1121 }
1122
1123
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)1124 int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len,
1125 const u8 *order, size_t order_len,
1126 const u8 *privkey, size_t privkey_len,
1127 const u8 *pubkey, size_t pubkey_len,
1128 u8 *secret, size_t *len)
1129 {
1130 int ret = -1;
1131 DhKey *dh;
1132 word32 secret_sz;
1133
1134 dh = os_malloc(sizeof(DhKey));
1135 if (!dh)
1136 return -1;
1137 wc_InitDhKey(dh);
1138
1139 if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0)
1140 goto done;
1141
1142 if (wc_DhAgree(dh, secret, &secret_sz, privkey, privkey_len, pubkey,
1143 pubkey_len) != 0)
1144 goto done;
1145
1146 *len = secret_sz;
1147 ret = 0;
1148 done:
1149 wc_FreeDhKey(dh);
1150 os_free(dh);
1151 return ret;
1152 }
1153
1154
1155 #ifdef CONFIG_FIPS
crypto_get_random(void * buf,size_t len)1156 int crypto_get_random(void *buf, size_t len)
1157 {
1158 int ret = 0;
1159 WC_RNG rng;
1160
1161 if (wc_InitRng(&rng) != 0)
1162 return -1;
1163 if (wc_RNG_GenerateBlock(&rng, buf, len) != 0)
1164 ret = -1;
1165 wc_FreeRng(&rng);
1166 return ret;
1167 }
1168 #endif /* CONFIG_FIPS */
1169
1170
1171 #if defined(EAP_PWD) || defined(EAP_SERVER_PWD)
1172 struct crypto_hash {
1173 Hmac hmac;
1174 int size;
1175 };
1176
1177
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)1178 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
1179 size_t key_len)
1180 {
1181 struct crypto_hash *ret = NULL;
1182 struct crypto_hash *hash;
1183 int type;
1184
1185 hash = os_zalloc(sizeof(*hash));
1186 if (!hash)
1187 goto done;
1188
1189 switch (alg) {
1190 #ifndef NO_MD5
1191 case CRYPTO_HASH_ALG_HMAC_MD5:
1192 hash->size = 16;
1193 type = WC_MD5;
1194 break;
1195 #endif /* NO_MD5 */
1196 #ifndef NO_SHA
1197 case CRYPTO_HASH_ALG_HMAC_SHA1:
1198 type = WC_SHA;
1199 hash->size = 20;
1200 break;
1201 #endif /* NO_SHA */
1202 #ifdef CONFIG_SHA256
1203 #ifndef NO_SHA256
1204 case CRYPTO_HASH_ALG_HMAC_SHA256:
1205 type = WC_SHA256;
1206 hash->size = 32;
1207 break;
1208 #endif /* NO_SHA256 */
1209 #endif /* CONFIG_SHA256 */
1210 default:
1211 goto done;
1212 }
1213
1214 if (wc_HmacInit(&hash->hmac, NULL, INVALID_DEVID) != 0 ||
1215 wc_HmacSetKey(&hash->hmac, type, key, key_len) != 0)
1216 goto done;
1217
1218 ret = hash;
1219 hash = NULL;
1220 done:
1221 os_free(hash);
1222 return ret;
1223 }
1224
1225
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)1226 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
1227 {
1228 if (!ctx)
1229 return;
1230 wc_HmacUpdate(&ctx->hmac, data, len);
1231 }
1232
1233
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)1234 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
1235 {
1236 int ret = 0;
1237
1238 if (!ctx)
1239 return -2;
1240
1241 if (!mac || !len)
1242 goto done;
1243
1244 if (wc_HmacFinal(&ctx->hmac, mac) != 0) {
1245 ret = -1;
1246 goto done;
1247 }
1248
1249 *len = ctx->size;
1250 ret = 0;
1251 done:
1252 bin_clear_free(ctx, sizeof(*ctx));
1253 if (TEST_FAIL())
1254 return -1;
1255 return ret;
1256 }
1257
1258 #endif
1259
1260
omac1_aes_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1261 int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
1262 const u8 *addr[], const size_t *len, u8 *mac)
1263 {
1264 Cmac cmac;
1265 size_t i;
1266 word32 sz;
1267
1268 if (TEST_FAIL())
1269 return -1;
1270
1271 if (wc_InitCmac(&cmac, key, key_len, WC_CMAC_AES, NULL) != 0)
1272 return -1;
1273
1274 for (i = 0; i < num_elem; i++)
1275 if (wc_CmacUpdate(&cmac, addr[i], len[i]) != 0)
1276 return -1;
1277
1278 sz = AES_BLOCK_SIZE;
1279 if (wc_CmacFinal(&cmac, mac, &sz) != 0 || sz != AES_BLOCK_SIZE)
1280 return -1;
1281
1282 return 0;
1283 }
1284
1285
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)1286 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1287 const u8 *addr[], const size_t *len, u8 *mac)
1288 {
1289 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1290 }
1291
1292
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1293 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1294 {
1295 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1296 }
1297
1298
omac1_aes_256(const u8 * key,const u8 * data,size_t data_len,u8 * mac)1299 int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1300 {
1301 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1302 }
1303
1304
crypto_bignum_init(void)1305 struct crypto_bignum * crypto_bignum_init(void)
1306 {
1307 mp_int *a;
1308
1309 if (TEST_FAIL())
1310 return NULL;
1311
1312 a = os_malloc(sizeof(*a));
1313 if (!a || mp_init(a) != MP_OKAY) {
1314 os_free(a);
1315 a = NULL;
1316 }
1317
1318 return (struct crypto_bignum *) a;
1319 }
1320
1321
crypto_bignum_init_set(const u8 * buf,size_t len)1322 struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
1323 {
1324 mp_int *a;
1325
1326 if (TEST_FAIL())
1327 return NULL;
1328
1329 a = (mp_int *) crypto_bignum_init();
1330 if (!a)
1331 return NULL;
1332
1333 if (mp_read_unsigned_bin(a, buf, len) != MP_OKAY) {
1334 os_free(a);
1335 a = NULL;
1336 }
1337
1338 return (struct crypto_bignum *) a;
1339 }
1340
1341
crypto_bignum_init_uint(unsigned int val)1342 struct crypto_bignum * crypto_bignum_init_uint(unsigned int val)
1343 {
1344 mp_int *a;
1345
1346 if (TEST_FAIL())
1347 return NULL;
1348
1349 a = (mp_int *) crypto_bignum_init();
1350 if (!a)
1351 return NULL;
1352
1353 if (mp_set_int(a, val) != MP_OKAY) {
1354 os_free(a);
1355 a = NULL;
1356 }
1357
1358 return (struct crypto_bignum *) a;
1359 }
1360
1361
crypto_bignum_deinit(struct crypto_bignum * n,int clear)1362 void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1363 {
1364 if (!n)
1365 return;
1366
1367 if (clear)
1368 mp_forcezero((mp_int *) n);
1369 mp_clear((mp_int *) n);
1370 os_free((mp_int *) n);
1371 }
1372
1373
crypto_bignum_to_bin(const struct crypto_bignum * a,u8 * buf,size_t buflen,size_t padlen)1374 int crypto_bignum_to_bin(const struct crypto_bignum *a,
1375 u8 *buf, size_t buflen, size_t padlen)
1376 {
1377 int num_bytes, offset;
1378
1379 if (TEST_FAIL())
1380 return -1;
1381
1382 if (padlen > buflen)
1383 return -1;
1384
1385 num_bytes = (mp_count_bits((mp_int *) a) + 7) / 8;
1386 if ((size_t) num_bytes > buflen)
1387 return -1;
1388 if (padlen > (size_t) num_bytes)
1389 offset = padlen - num_bytes;
1390 else
1391 offset = 0;
1392
1393 os_memset(buf, 0, offset);
1394 mp_to_unsigned_bin((mp_int *) a, buf + offset);
1395
1396 return num_bytes + offset;
1397 }
1398
1399
crypto_bignum_rand(struct crypto_bignum * r,const struct crypto_bignum * m)1400 int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
1401 {
1402 int ret = 0;
1403 WC_RNG rng;
1404 size_t len;
1405 u8 *buf;
1406
1407 if (TEST_FAIL())
1408 return -1;
1409 if (wc_InitRng(&rng) != 0)
1410 return -1;
1411 len = (mp_count_bits((mp_int *) m) + 7) / 8;
1412 buf = os_malloc(len);
1413 if (!buf || wc_RNG_GenerateBlock(&rng, buf, len) != 0 ||
1414 mp_read_unsigned_bin((mp_int *) r, buf, len) != MP_OKAY ||
1415 mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0)
1416 ret = -1;
1417 wc_FreeRng(&rng);
1418 bin_clear_free(buf, len);
1419 return ret;
1420 }
1421
1422
crypto_bignum_add(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)1423 int crypto_bignum_add(const struct crypto_bignum *a,
1424 const struct crypto_bignum *b,
1425 struct crypto_bignum *r)
1426 {
1427 return mp_add((mp_int *) a, (mp_int *) b,
1428 (mp_int *) r) == MP_OKAY ? 0 : -1;
1429 }
1430
1431
crypto_bignum_mod(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)1432 int crypto_bignum_mod(const struct crypto_bignum *a,
1433 const struct crypto_bignum *m,
1434 struct crypto_bignum *r)
1435 {
1436 return mp_mod((mp_int *) a, (mp_int *) m,
1437 (mp_int *) r) == MP_OKAY ? 0 : -1;
1438 }
1439
1440
crypto_bignum_exptmod(const struct crypto_bignum * b,const struct crypto_bignum * e,const struct crypto_bignum * m,struct crypto_bignum * r)1441 int crypto_bignum_exptmod(const struct crypto_bignum *b,
1442 const struct crypto_bignum *e,
1443 const struct crypto_bignum *m,
1444 struct crypto_bignum *r)
1445 {
1446 if (TEST_FAIL())
1447 return -1;
1448
1449 return mp_exptmod((mp_int *) b, (mp_int *) e, (mp_int *) m,
1450 (mp_int *) r) == MP_OKAY ? 0 : -1;
1451 }
1452
1453
crypto_bignum_inverse(const struct crypto_bignum * a,const struct crypto_bignum * m,struct crypto_bignum * r)1454 int crypto_bignum_inverse(const struct crypto_bignum *a,
1455 const struct crypto_bignum *m,
1456 struct crypto_bignum *r)
1457 {
1458 if (TEST_FAIL())
1459 return -1;
1460
1461 return mp_invmod((mp_int *) a, (mp_int *) m,
1462 (mp_int *) r) == MP_OKAY ? 0 : -1;
1463 }
1464
1465
crypto_bignum_sub(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * r)1466 int crypto_bignum_sub(const struct crypto_bignum *a,
1467 const struct crypto_bignum *b,
1468 struct crypto_bignum *r)
1469 {
1470 if (TEST_FAIL())
1471 return -1;
1472
1473 return mp_sub((mp_int *) a, (mp_int *) b,
1474 (mp_int *) r) == MP_OKAY ? 0 : -1;
1475 }
1476
1477
crypto_bignum_div(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * d)1478 int crypto_bignum_div(const struct crypto_bignum *a,
1479 const struct crypto_bignum *b,
1480 struct crypto_bignum *d)
1481 {
1482 if (TEST_FAIL())
1483 return -1;
1484
1485 return mp_div((mp_int *) a, (mp_int *) b, (mp_int *) d,
1486 NULL) == MP_OKAY ? 0 : -1;
1487 }
1488
1489
crypto_bignum_addmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * c,struct crypto_bignum * d)1490 int crypto_bignum_addmod(const struct crypto_bignum *a,
1491 const struct crypto_bignum *b,
1492 const struct crypto_bignum *c,
1493 struct crypto_bignum *d)
1494 {
1495 if (TEST_FAIL())
1496 return -1;
1497
1498 return mp_addmod((mp_int *) a, (mp_int *) b, (mp_int *) c,
1499 (mp_int *) d) == MP_OKAY ? 0 : -1;
1500 }
1501
1502
crypto_bignum_mulmod(const struct crypto_bignum * a,const struct crypto_bignum * b,const struct crypto_bignum * m,struct crypto_bignum * d)1503 int crypto_bignum_mulmod(const struct crypto_bignum *a,
1504 const struct crypto_bignum *b,
1505 const struct crypto_bignum *m,
1506 struct crypto_bignum *d)
1507 {
1508 if (TEST_FAIL())
1509 return -1;
1510
1511 return mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) m,
1512 (mp_int *) d) == MP_OKAY ? 0 : -1;
1513 }
1514
1515
crypto_bignum_sqrmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1516 int crypto_bignum_sqrmod(const struct crypto_bignum *a,
1517 const struct crypto_bignum *b,
1518 struct crypto_bignum *c)
1519 {
1520 if (TEST_FAIL())
1521 return -1;
1522
1523 return mp_sqrmod((mp_int *) a, (mp_int *) b,
1524 (mp_int *) c) == MP_OKAY ? 0 : -1;
1525 }
1526
1527
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)1528 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1529 struct crypto_bignum *r)
1530 {
1531 if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1532 return -1;
1533 mp_rshb((mp_int *) r, n);
1534 return 0;
1535 }
1536
1537
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)1538 int crypto_bignum_cmp(const struct crypto_bignum *a,
1539 const struct crypto_bignum *b)
1540 {
1541 return mp_cmp((mp_int *) a, (mp_int *) b);
1542 }
1543
1544
crypto_bignum_is_zero(const struct crypto_bignum * a)1545 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1546 {
1547 return mp_iszero((mp_int *) a);
1548 }
1549
1550
crypto_bignum_is_one(const struct crypto_bignum * a)1551 int crypto_bignum_is_one(const struct crypto_bignum *a)
1552 {
1553 return mp_isone((const mp_int *) a);
1554 }
1555
crypto_bignum_is_odd(const struct crypto_bignum * a)1556 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1557 {
1558 return mp_isodd((mp_int *) a);
1559 }
1560
1561
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)1562 int crypto_bignum_legendre(const struct crypto_bignum *a,
1563 const struct crypto_bignum *p)
1564 {
1565 mp_int t;
1566 int ret;
1567 int res = -2;
1568
1569 if (TEST_FAIL())
1570 return -2;
1571
1572 if (mp_init(&t) != MP_OKAY)
1573 return -2;
1574
1575 /* t = (p-1) / 2 */
1576 ret = mp_sub_d((mp_int *) p, 1, &t);
1577 if (ret == MP_OKAY)
1578 mp_rshb(&t, 1);
1579 if (ret == MP_OKAY)
1580 ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1581 if (ret == MP_OKAY) {
1582 if (mp_isone(&t))
1583 res = 1;
1584 else if (mp_iszero(&t))
1585 res = 0;
1586 else
1587 res = -1;
1588 }
1589
1590 mp_clear(&t);
1591 return res;
1592 }
1593
1594
1595 #ifdef CONFIG_ECC
1596
crypto_ec_group_2_id(int group)1597 static int crypto_ec_group_2_id(int group)
1598 {
1599 switch (group) {
1600 case 19:
1601 return ECC_SECP256R1;
1602 case 20:
1603 return ECC_SECP384R1;
1604 case 21:
1605 return ECC_SECP521R1;
1606 case 25:
1607 return ECC_SECP192R1;
1608 case 26:
1609 return ECC_SECP224R1;
1610 #ifdef HAVE_ECC_BRAINPOOL
1611 case 27:
1612 return ECC_BRAINPOOLP224R1;
1613 case 28:
1614 return ECC_BRAINPOOLP256R1;
1615 case 29:
1616 return ECC_BRAINPOOLP384R1;
1617 case 30:
1618 return ECC_BRAINPOOLP512R1;
1619 #endif /* HAVE_ECC_BRAINPOOL */
1620 default:
1621 LOG_WOLF_ERROR_VA("Unsupported curve (id=%d) in EC key", group);
1622 return ECC_CURVE_INVALID;
1623 }
1624 }
1625
1626
1627 int ecc_map(ecc_point *, mp_int *, mp_digit);
1628 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1629 mp_int *a, mp_int *modulus, mp_digit mp);
1630
1631 struct crypto_ec {
1632 ecc_key *key;
1633 #ifdef CONFIG_DPP
1634 ecc_point *g; /* Only used in DPP for now */
1635 #endif /* CONFIG_DPP */
1636 mp_int a;
1637 mp_int prime;
1638 mp_int order;
1639 mp_digit mont_b;
1640 mp_int b;
1641 int curve_id;
1642 bool own_key; /* Should we free the `key` */
1643 };
1644
1645
crypto_ec_init(int group)1646 struct crypto_ec * crypto_ec_init(int group)
1647 {
1648 int built = 0;
1649 struct crypto_ec *e;
1650 int curve_id = crypto_ec_group_2_id(group);
1651 int err;
1652
1653 if (curve_id == ECC_CURVE_INVALID) {
1654 LOG_INVALID_PARAMETERS();
1655 return NULL;
1656 }
1657
1658 e = os_zalloc(sizeof(*e));
1659 if (!e) {
1660 LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
1661 return NULL;
1662 }
1663
1664 e->curve_id = curve_id;
1665 e->own_key = true;
1666 e->key = ecc_key_init();
1667 if (!e->key) {
1668 LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init);
1669 goto done;
1670 }
1671
1672 err = wc_ecc_set_curve(e->key, 0, curve_id);
1673 if (err != 0) {
1674 LOG_WOLF_ERROR_FUNC(wc_ecc_set_curve, err);
1675 goto done;
1676 }
1677 #ifdef CONFIG_DPP
1678 e->g = wc_ecc_new_point();
1679 if (!e->g) {
1680 LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
1681 goto done;
1682 }
1683 #ifdef CONFIG_FIPS
1684 /* Setup generator manually in FIPS mode */
1685 if (!e->key->dp) {
1686 LOG_WOLF_ERROR_FUNC_NULL(e->key->dp);
1687 goto done;
1688 }
1689 err = mp_read_radix(e->g->x, e->key->dp->Gx, MP_RADIX_HEX);
1690 if (err != MP_OKAY) {
1691 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1692 goto done;
1693 }
1694 err = mp_read_radix(e->g->y, e->key->dp->Gy, MP_RADIX_HEX);
1695 if (err != MP_OKAY) {
1696 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1697 goto done;
1698 }
1699 err = mp_set(e->g->z, 1);
1700 if (err != MP_OKAY) {
1701 LOG_WOLF_ERROR_FUNC(mp_set, err);
1702 goto done;
1703 }
1704 #else /* CONFIG_FIPS */
1705 err = wc_ecc_get_generator(e->g, wc_ecc_get_curve_idx(curve_id));
1706 if (err != MP_OKAY) {
1707 LOG_WOLF_ERROR_FUNC(wc_ecc_get_generator, err);
1708 goto done;
1709 }
1710 #endif /* CONFIG_FIPS */
1711 #endif /* CONFIG_DPP */
1712 err = mp_init_multi(&e->a, &e->prime, &e->order, &e->b, NULL, NULL);
1713 if (err != MP_OKAY) {
1714 LOG_WOLF_ERROR_FUNC(mp_init_multi, err);
1715 goto done;
1716 }
1717 err = mp_read_radix(&e->a, e->key->dp->Af, 16);
1718 if (err != MP_OKAY) {
1719 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1720 goto done;
1721 }
1722 err = mp_read_radix(&e->b, e->key->dp->Bf, 16);
1723 if (err != MP_OKAY) {
1724 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1725 goto done;
1726 }
1727 err = mp_read_radix(&e->prime, e->key->dp->prime, 16);
1728 if (err != MP_OKAY) {
1729 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1730 goto done;
1731 }
1732 err = mp_read_radix(&e->order, e->key->dp->order, 16);
1733 if (err != MP_OKAY) {
1734 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1735 goto done;
1736 }
1737 err = mp_montgomery_setup(&e->prime, &e->mont_b);
1738 if (err != MP_OKAY) {
1739 LOG_WOLF_ERROR_FUNC(mp_montgomery_setup, err);
1740 goto done;
1741 }
1742
1743 built = 1;
1744 done:
1745 if (!built) {
1746 crypto_ec_deinit(e);
1747 e = NULL;
1748 }
1749 return e;
1750 }
1751
1752
crypto_ec_deinit(struct crypto_ec * e)1753 void crypto_ec_deinit(struct crypto_ec* e)
1754 {
1755 if (!e)
1756 return;
1757
1758 mp_clear(&e->b);
1759 mp_clear(&e->order);
1760 mp_clear(&e->prime);
1761 mp_clear(&e->a);
1762 #ifdef CONFIG_DPP
1763 wc_ecc_del_point(e->g);
1764 #endif /* CONFIG_DPP */
1765 if (e->own_key)
1766 ecc_key_deinit(e->key);
1767 os_free(e);
1768 }
1769
1770
crypto_ec_point_init(struct crypto_ec * e)1771 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1772 {
1773 if (TEST_FAIL())
1774 return NULL;
1775 if (!e)
1776 return NULL;
1777 return (struct crypto_ec_point *) wc_ecc_new_point();
1778 }
1779
1780
crypto_ec_prime_len(struct crypto_ec * e)1781 size_t crypto_ec_prime_len(struct crypto_ec *e)
1782 {
1783 return (mp_count_bits(&e->prime) + 7) / 8;
1784 }
1785
1786
crypto_ec_prime_len_bits(struct crypto_ec * e)1787 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1788 {
1789 return mp_count_bits(&e->prime);
1790 }
1791
1792
crypto_ec_order_len(struct crypto_ec * e)1793 size_t crypto_ec_order_len(struct crypto_ec *e)
1794 {
1795 return (mp_count_bits(&e->order) + 7) / 8;
1796 }
1797
1798
crypto_ec_get_prime(struct crypto_ec * e)1799 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1800 {
1801 return (const struct crypto_bignum *) &e->prime;
1802 }
1803
1804
crypto_ec_get_order(struct crypto_ec * e)1805 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1806 {
1807 return (const struct crypto_bignum *) &e->order;
1808 }
1809
1810
crypto_ec_get_a(struct crypto_ec * e)1811 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1812 {
1813 return (const struct crypto_bignum *) &e->a;
1814 }
1815
1816
crypto_ec_get_b(struct crypto_ec * e)1817 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1818 {
1819 return (const struct crypto_bignum *) &e->b;
1820 }
1821
1822
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)1823 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1824 {
1825 ecc_point *point = (ecc_point *) p;
1826
1827 if (!p)
1828 return;
1829
1830 if (clear) {
1831 #ifdef CONFIG_FIPS
1832 mp_forcezero(point->x);
1833 mp_forcezero(point->y);
1834 mp_forcezero(point->z);
1835 #else /* CONFIG_FIPS */
1836 wc_ecc_forcezero_point(point);
1837 #endif /* CONFIG_FIPS */
1838 }
1839 wc_ecc_del_point(point);
1840 }
1841
1842
1843 #ifdef CONFIG_DPP
crypto_ec_get_generator(struct crypto_ec * e)1844 const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
1845 {
1846 return (const struct crypto_ec_point *) e->g;
1847 }
1848 #endif /* CONFIG_DPP */
1849
1850
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)1851 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1852 struct crypto_bignum *x)
1853 {
1854 return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1855 }
1856
1857
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)1858 int crypto_ec_point_to_bin(struct crypto_ec *e,
1859 const struct crypto_ec_point *point, u8 *x, u8 *y)
1860 {
1861 ecc_point *p = (ecc_point *) point;
1862 int len;
1863 int err;
1864
1865 if (TEST_FAIL())
1866 return -1;
1867
1868 if (!mp_isone(p->z)) {
1869 err = ecc_map(p, &e->prime, e->mont_b);
1870 if (err != MP_OKAY) {
1871 LOG_WOLF_ERROR_FUNC(ecc_map, err);
1872 return -1;
1873 }
1874 }
1875
1876 len = wc_ecc_get_curve_size_from_id(e->curve_id);
1877 if (len <= 0) {
1878 LOG_WOLF_ERROR_FUNC(wc_ecc_get_curve_size_from_id, len);
1879 LOG_WOLF_ERROR_VA("wc_ecc_get_curve_size_from_id error for curve_id %d", e->curve_id);
1880 return -1;
1881 }
1882
1883 if (x) {
1884 if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1885 (size_t) len, (size_t) len) <= 0) {
1886 LOG_WOLF_ERROR_FUNC(crypto_bignum_to_bin, -1);
1887 return -1;
1888 }
1889 }
1890
1891 if (y) {
1892 if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1893 (size_t) len, (size_t) len) <= 0) {
1894 LOG_WOLF_ERROR_FUNC(crypto_bignum_to_bin, -1);
1895 return -1;
1896 }
1897 }
1898
1899 return 0;
1900 }
1901
1902
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)1903 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1904 const u8 *val)
1905 {
1906 ecc_point *point = NULL;
1907 int loaded = 0;
1908
1909 if (TEST_FAIL())
1910 return NULL;
1911
1912 point = wc_ecc_new_point();
1913 if (!point)
1914 goto done;
1915
1916 if (mp_read_unsigned_bin(point->x, val, e->key->dp->size) != MP_OKAY)
1917 goto done;
1918 val += e->key->dp->size;
1919 if (mp_read_unsigned_bin(point->y, val, e->key->dp->size) != MP_OKAY)
1920 goto done;
1921 mp_set(point->z, 1);
1922
1923 loaded = 1;
1924 done:
1925 if (!loaded) {
1926 wc_ecc_del_point(point);
1927 point = NULL;
1928 }
1929 return (struct crypto_ec_point *) point;
1930 }
1931
1932
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)1933 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1934 const struct crypto_ec_point *b,
1935 struct crypto_ec_point *c)
1936 {
1937 mp_int mu;
1938 ecc_point *ta = NULL, *tb = NULL;
1939 ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1940 mp_int *modulus = &e->prime;
1941 int ret;
1942
1943 if (TEST_FAIL())
1944 return -1;
1945
1946 ret = mp_init(&mu);
1947 if (ret != MP_OKAY)
1948 return -1;
1949
1950 ret = mp_montgomery_calc_normalization(&mu, modulus);
1951 if (ret != MP_OKAY) {
1952 mp_clear(&mu);
1953 return -1;
1954 }
1955
1956 if (!mp_isone(&mu)) {
1957 ta = wc_ecc_new_point();
1958 if (!ta) {
1959 mp_clear(&mu);
1960 return -1;
1961 }
1962 tb = wc_ecc_new_point();
1963 if (!tb) {
1964 wc_ecc_del_point(ta);
1965 mp_clear(&mu);
1966 return -1;
1967 }
1968
1969 if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1970 mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1971 mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1972 mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1973 mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1974 mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1975 ret = -1;
1976 goto end;
1977 }
1978 pa = ta;
1979 pb = tb;
1980 }
1981
1982 ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1983 &e->prime, e->mont_b);
1984 if (ret != 0) {
1985 ret = -1;
1986 goto end;
1987 }
1988
1989 if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1990 ret = -1;
1991 else
1992 ret = 0;
1993 end:
1994 wc_ecc_del_point(tb);
1995 wc_ecc_del_point(ta);
1996 mp_clear(&mu);
1997 return ret;
1998 }
1999
2000
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)2001 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
2002 const struct crypto_bignum *b,
2003 struct crypto_ec_point *res)
2004 {
2005 int ret;
2006
2007 if (TEST_FAIL())
2008 return -1;
2009
2010 ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
2011 &e->a, &e->prime, 1);
2012 return ret == 0 ? 0 : -1;
2013 }
2014
2015
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)2016 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
2017 {
2018 ecc_point *point = (ecc_point *) p;
2019
2020 if (TEST_FAIL())
2021 return -1;
2022
2023 if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
2024 return -1;
2025
2026 return 0;
2027 }
2028
2029
2030 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)2031 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
2032 const struct crypto_bignum *x)
2033 {
2034 mp_int *y2;
2035
2036 if (TEST_FAIL())
2037 return NULL;
2038
2039 /* y^2 = x^3 + ax + b = (x^2 + a)x + b */
2040 y2 = (mp_int *) crypto_bignum_init();
2041 if (!y2 ||
2042 mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
2043 mp_addmod(y2, &e->a, &e->prime, y2) != 0 ||
2044 mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
2045 mp_addmod(y2, &e->b, &e->prime, y2) != 0) {
2046 mp_clear(y2);
2047 os_free(y2);
2048 y2 = NULL;
2049 }
2050
2051 return (struct crypto_bignum *) y2;
2052 }
2053
2054
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)2055 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
2056 const struct crypto_ec_point *p)
2057 {
2058 return wc_ecc_point_is_at_infinity((ecc_point *) p);
2059 }
2060
2061
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)2062 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
2063 const struct crypto_ec_point *p)
2064 {
2065 return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
2066 MP_OKAY;
2067 }
2068
2069
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)2070 int crypto_ec_point_cmp(const struct crypto_ec *e,
2071 const struct crypto_ec_point *a,
2072 const struct crypto_ec_point *b)
2073 {
2074 return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
2075 }
2076
2077 struct crypto_ec_key {
2078 ecc_key *eckey;
2079 WC_RNG *rng; /* Needs to be initialized before use.
2080 * *NOT* initialized in crypto_ec_key_init */
2081 };
2082
2083
2084 struct crypto_ecdh {
2085 struct crypto_ec *ec;
2086 WC_RNG *rng;
2087 };
2088
_crypto_ecdh_init(int group)2089 static struct crypto_ecdh * _crypto_ecdh_init(int group)
2090 {
2091 struct crypto_ecdh *ecdh = NULL;
2092 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2093 int ret;
2094 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2095
2096 ecdh = os_zalloc(sizeof(*ecdh));
2097 if (!ecdh) {
2098 LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
2099 return NULL;
2100 }
2101
2102 ecdh->rng = wc_rng_init();
2103 if (!ecdh->rng) {
2104 LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
2105 goto fail;
2106 }
2107
2108 ecdh->ec = crypto_ec_init(group);
2109 if (!ecdh->ec) {
2110 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_init);
2111 goto fail;
2112 }
2113
2114 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2115 ret = wc_ecc_set_rng(ecdh->ec->key, ecdh->rng);
2116 if (ret != 0) {
2117 LOG_WOLF_ERROR_FUNC(wc_ecc_set_rng, ret);
2118 goto fail;
2119 }
2120 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2121
2122 return ecdh;
2123 fail:
2124 crypto_ecdh_deinit(ecdh);
2125 return NULL;
2126 }
2127
2128
crypto_ecdh_init(int group)2129 struct crypto_ecdh * crypto_ecdh_init(int group)
2130 {
2131 struct crypto_ecdh *ret = NULL;
2132 int err;
2133
2134 ret = _crypto_ecdh_init(group);
2135
2136 if (!ret) {
2137 LOG_WOLF_ERROR_FUNC_NULL(_crypto_ecdh_init);
2138 return NULL;
2139 }
2140
2141 err = wc_ecc_make_key_ex(ret->rng, 0, ret->ec->key,
2142 crypto_ec_group_2_id(group));
2143 if (err != MP_OKAY) {
2144 LOG_WOLF_ERROR_FUNC(wc_ecc_make_key_ex, err);
2145 crypto_ecdh_deinit(ret);
2146 ret = NULL;
2147 }
2148
2149 return ret;
2150 }
2151
2152
crypto_ecdh_init2(int group,struct crypto_ec_key * own_key)2153 struct crypto_ecdh * crypto_ecdh_init2(int group, struct crypto_ec_key *own_key)
2154 {
2155 struct crypto_ecdh *ret = NULL;
2156
2157 if (!own_key || crypto_ec_key_group(own_key) != group) {
2158 LOG_INVALID_PARAMETERS();
2159 return NULL;
2160 }
2161
2162 ret = _crypto_ecdh_init(group);
2163 if (ret) {
2164 /* Already init'ed to the right group. Enough to substitute the
2165 * key. */
2166 ecc_key_deinit(ret->ec->key);
2167 ret->ec->key = own_key->eckey;
2168 ret->ec->own_key = false;
2169 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2170 if (!ret->ec->key->rng) {
2171 int err = wc_ecc_set_rng(ret->ec->key, ret->rng);
2172
2173 if (err != 0)
2174 LOG_WOLF_ERROR_FUNC(wc_ecc_set_rng, err);
2175 }
2176 #endif /* ECC_TIMING_RESISTANT && !CONFIG_FIPS */
2177 }
2178
2179 return ret;
2180 }
2181
2182
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)2183 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
2184 {
2185 if (ecdh) {
2186 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2187 /* Disassociate the rng */
2188 if (ecdh->ec && ecdh->ec->key &&
2189 ecdh->ec->key->rng == ecdh->rng)
2190 (void) wc_ecc_set_rng(ecdh->ec->key, NULL);
2191 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2192 crypto_ec_deinit(ecdh->ec);
2193 wc_rng_deinit(ecdh->rng);
2194 os_free(ecdh);
2195 }
2196 }
2197
2198
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)2199 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
2200 {
2201 struct wpabuf *buf = NULL;
2202 int ret;
2203 int len = ecdh->ec->key->dp->size;
2204
2205 buf = wpabuf_alloc(inc_y ? 2 * len : len);
2206 if (!buf)
2207 goto fail;
2208
2209 ret = crypto_bignum_to_bin((struct crypto_bignum *)
2210 ecdh->ec->key->pubkey.x, wpabuf_put(buf, len),
2211 len, len);
2212 if (ret < 0)
2213 goto fail;
2214 if (inc_y) {
2215 ret = crypto_bignum_to_bin((struct crypto_bignum *)
2216 ecdh->ec->key->pubkey.y,
2217 wpabuf_put(buf, len), len, len);
2218 if (ret < 0)
2219 goto fail;
2220 }
2221
2222 done:
2223 return buf;
2224 fail:
2225 wpabuf_free(buf);
2226 buf = NULL;
2227 goto done;
2228 }
2229
2230
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)2231 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
2232 const u8 *key, size_t len)
2233 {
2234 int ret;
2235 struct wpabuf *pubkey = NULL;
2236 struct wpabuf *secret = NULL;
2237 word32 key_len = ecdh->ec->key->dp->size;
2238 ecc_point *point = NULL;
2239 size_t need_key_len = inc_y ? 2 * key_len : key_len;
2240
2241 if (len < need_key_len) {
2242 LOG_WOLF_ERROR("key len too small");
2243 goto fail;
2244 }
2245 pubkey = wpabuf_alloc(1 + 2 * key_len);
2246 if (!pubkey) {
2247 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2248 goto fail;
2249 }
2250 wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
2251 wpabuf_put_data(pubkey, key, need_key_len);
2252
2253 point = wc_ecc_new_point();
2254 if (!point) {
2255 LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
2256 goto fail;
2257 }
2258
2259 ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
2260 ecdh->ec->key->idx, point);
2261 if (ret != MP_OKAY) {
2262 LOG_WOLF_ERROR_FUNC(wc_ecc_import_point_der, ret);
2263 goto fail;
2264 }
2265
2266 secret = wpabuf_alloc(key_len);
2267 if (!secret) {
2268 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2269 goto fail;
2270 }
2271
2272 ret = wc_ecc_shared_secret_ex(ecdh->ec->key, point,
2273 wpabuf_put(secret, key_len), &key_len);
2274 if (ret != MP_OKAY) {
2275 LOG_WOLF_ERROR_FUNC(wc_ecc_shared_secret_ex, ret);
2276 goto fail;
2277 }
2278
2279 done:
2280 wc_ecc_del_point(point);
2281 wpabuf_free(pubkey);
2282 return secret;
2283 fail:
2284 wpabuf_free(secret);
2285 secret = NULL;
2286 goto done;
2287 }
2288
2289
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)2290 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
2291 {
2292 return crypto_ec_prime_len(ecdh->ec);
2293 }
2294
crypto_ec_key_init(void)2295 static struct crypto_ec_key * crypto_ec_key_init(void)
2296 {
2297 struct crypto_ec_key *key;
2298
2299 key = os_zalloc(sizeof(struct crypto_ec_key));
2300 if (key) {
2301 key->eckey = ecc_key_init();
2302 /* Omit key->rng initialization because it seeds itself and thus
2303 * consumes entropy that may never be used. Lazy initialize when
2304 * necessary. */
2305 if (!key->eckey) {
2306 LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init);
2307 crypto_ec_key_deinit(key);
2308 key = NULL;
2309 }
2310 }
2311 return key;
2312 }
2313
2314
crypto_ec_key_deinit(struct crypto_ec_key * key)2315 void crypto_ec_key_deinit(struct crypto_ec_key *key)
2316 {
2317 if (key) {
2318 ecc_key_deinit(key->eckey);
2319 wc_rng_deinit(key->rng);
2320 os_free(key);
2321 }
2322 }
2323
2324
crypto_ec_key_init_rng(struct crypto_ec_key * key)2325 static WC_RNG * crypto_ec_key_init_rng(struct crypto_ec_key *key)
2326 {
2327 if (!key->rng) {
2328 /* Lazy init key->rng */
2329 key->rng = wc_rng_init();
2330 if (!key->rng)
2331 LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
2332 }
2333 return key->rng;
2334 }
2335
2336
crypto_ec_key_parse_priv(const u8 * der,size_t der_len)2337 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
2338 {
2339 struct crypto_ec_key *ret;
2340 word32 idx = 0;
2341 int err;
2342
2343 ret = crypto_ec_key_init();
2344 if (!ret) {
2345 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2346 goto fail;
2347 }
2348
2349 err = wc_EccPrivateKeyDecode(der, &idx, ret->eckey, (word32) der_len);
2350 if (err != 0) {
2351 LOG_WOLF_ERROR_FUNC(wc_EccPrivateKeyDecode, err);
2352 goto fail;
2353 }
2354
2355 return ret;
2356 fail:
2357 if (ret)
2358 crypto_ec_key_deinit(ret);
2359 return NULL;
2360 }
2361
2362
crypto_ec_key_group(struct crypto_ec_key * key)2363 int crypto_ec_key_group(struct crypto_ec_key *key)
2364 {
2365
2366 if (!key || !key->eckey || !key->eckey->dp) {
2367 LOG_INVALID_PARAMETERS();
2368 return -1;
2369 }
2370
2371 switch (key->eckey->dp->id) {
2372 case ECC_SECP256R1:
2373 return 19;
2374 case ECC_SECP384R1:
2375 return 20;
2376 case ECC_SECP521R1:
2377 return 21;
2378 case ECC_SECP192R1:
2379 return 25;
2380 case ECC_SECP224R1:
2381 return 26;
2382 #ifdef HAVE_ECC_BRAINPOOL
2383 case ECC_BRAINPOOLP224R1:
2384 return 27;
2385 case ECC_BRAINPOOLP256R1:
2386 return 28;
2387 case ECC_BRAINPOOLP384R1:
2388 return 29;
2389 case ECC_BRAINPOOLP512R1:
2390 return 30;
2391 #endif /* HAVE_ECC_BRAINPOOL */
2392 }
2393
2394 LOG_WOLF_ERROR_VA("Unsupported curve (id=%d) in EC key",
2395 key->eckey->dp->id);
2396 return -1;
2397 }
2398
2399
crypto_ec_key_gen_public_key(struct crypto_ec_key * key)2400 static int crypto_ec_key_gen_public_key(struct crypto_ec_key *key)
2401 {
2402 int err;
2403
2404 #ifdef WOLFSSL_OLD_FIPS
2405 err = wc_ecc_make_pub(key->eckey, NULL);
2406 #else /* WOLFSSL_OLD_FIPS */
2407 /* Have wolfSSL generate the public key to make it available for output
2408 */
2409 if (!crypto_ec_key_init_rng(key)) {
2410 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2411 return -1;
2412 }
2413
2414 err = wc_ecc_make_pub_ex(key->eckey, NULL, key->rng);
2415 #endif /* WOLFSSL_OLD_FIPS */
2416
2417 if (err != MP_OKAY) {
2418 LOG_WOLF_ERROR_FUNC(wc_ecc_make_pub_ex, err);
2419 return -1;
2420 }
2421
2422 return 0;
2423 }
2424
2425
crypto_ec_key_get_subject_public_key(struct crypto_ec_key * key)2426 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
2427 {
2428 int der_len;
2429 struct wpabuf *ret = NULL;
2430 int err;
2431
2432 if (!key || !key->eckey) {
2433 LOG_INVALID_PARAMETERS();
2434 goto fail;
2435 }
2436
2437 #ifdef WOLFSSL_OLD_FIPS
2438 if (key->eckey->type == ECC_PRIVATEKEY_ONLY &&
2439 crypto_ec_key_gen_public_key(key) != 0) {
2440 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2441 goto fail;
2442 }
2443 #endif /* WOLFSSL_OLD_FIPS */
2444
2445 der_len = err = wc_EccPublicKeyToDer_ex(key->eckey, NULL, 0, 1, 1);
2446 if (err == ECC_PRIVATEONLY_E) {
2447 if (crypto_ec_key_gen_public_key(key) != 0) {
2448 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2449 goto fail;
2450 }
2451 der_len = err = wc_EccPublicKeyToDer_ex(key->eckey, NULL, 0, 1,
2452 1);
2453 }
2454 if (err <= 0) {
2455 LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyDerSize, err);
2456 goto fail;
2457 }
2458
2459 ret = wpabuf_alloc(der_len);
2460 if (!ret) {
2461 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2462 goto fail;
2463 }
2464
2465 err = wc_EccPublicKeyToDer_ex(key->eckey, wpabuf_mhead(ret), der_len, 1,
2466 1);
2467 if (err == ECC_PRIVATEONLY_E) {
2468 if (crypto_ec_key_gen_public_key(key) != 0) {
2469 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2470 goto fail;
2471 }
2472 err = wc_EccPublicKeyToDer_ex(key->eckey, wpabuf_mhead(ret),
2473 der_len, 1, 1);
2474 }
2475 if (err <= 0) {
2476 LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyToDer, err);
2477 goto fail;
2478 }
2479 der_len = err;
2480 wpabuf_put(ret, der_len);
2481
2482 return ret;
2483
2484 fail:
2485 wpabuf_free(ret);
2486 return NULL;
2487 }
2488
2489
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)2490 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
2491 {
2492 word32 idx = 0;
2493 struct crypto_ec_key *ret = NULL;
2494 int err;
2495
2496 ret = crypto_ec_key_init();
2497 if (!ret) {
2498 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2499 goto fail;
2500 }
2501
2502 err = wc_EccPublicKeyDecode(der, &idx, ret->eckey, (word32) der_len);
2503 if (err != 0) {
2504 LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyDecode, err);
2505 goto fail;
2506 }
2507
2508 return ret;
2509 fail:
2510 crypto_ec_key_deinit(ret);
2511 return NULL;
2512 }
2513
2514
crypto_ec_key_sign(struct crypto_ec_key * key,const u8 * data,size_t len)2515 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
2516 size_t len)
2517 {
2518 int der_len;
2519 int err;
2520 word32 w32_der_len;
2521 struct wpabuf *ret = NULL;
2522
2523 if (!key || !key->eckey || !data || len == 0) {
2524 LOG_INVALID_PARAMETERS();
2525 goto fail;
2526 }
2527
2528 if (!crypto_ec_key_init_rng(key)) {
2529 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2530 goto fail;
2531 }
2532
2533 der_len = wc_ecc_sig_size(key->eckey);
2534 if (der_len <= 0) {
2535 LOG_WOLF_ERROR_FUNC(wc_ecc_sig_size, der_len);
2536 goto fail;
2537 }
2538
2539 ret = wpabuf_alloc(der_len);
2540 if (!ret) {
2541 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2542 goto fail;
2543 }
2544
2545 w32_der_len = (word32) der_len;
2546 err = wc_ecc_sign_hash(data, len, wpabuf_mhead(ret), &w32_der_len,
2547 key->rng, key->eckey);
2548 if (err != 0) {
2549 LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash, err);
2550 goto fail;
2551 }
2552 wpabuf_put(ret, w32_der_len);
2553
2554 return ret;
2555 fail:
2556 wpabuf_free(ret);
2557 return NULL;
2558 }
2559
2560
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)2561 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
2562 size_t len, const u8 *sig, size_t sig_len)
2563 {
2564 int res = 0;
2565
2566 if (!key || !key->eckey || !data || len == 0 || !sig || sig_len == 0) {
2567 LOG_INVALID_PARAMETERS();
2568 return -1;
2569 }
2570
2571 if (wc_ecc_verify_hash(sig, sig_len, data, len, &res, key->eckey) != 0)
2572 {
2573 LOG_WOLF_ERROR("wc_ecc_verify_hash failed");
2574 return -1;
2575 }
2576
2577 if (res != 1)
2578 LOG_WOLF_ERROR("crypto_ec_key_verify_signature failed");
2579
2580 return res;
2581 }
2582
2583 #endif /* CONFIG_ECC */
2584
2585 #ifdef CONFIG_DPP
2586
crypto_ec_key_get_ecprivate_key(struct crypto_ec_key * key,bool include_pub)2587 struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
2588 bool include_pub)
2589 {
2590 int len;
2591 int err;
2592 struct wpabuf *ret = NULL;
2593
2594 if (!key || !key->eckey) {
2595 LOG_INVALID_PARAMETERS();
2596 return NULL;
2597 }
2598
2599 #ifdef WOLFSSL_OLD_FIPS
2600 if (key->eckey->type != ECC_PRIVATEKEY &&
2601 key->eckey->type != ECC_PRIVATEKEY_ONLY) {
2602 LOG_INVALID_PARAMETERS();
2603 return NULL;
2604 }
2605 #endif /* WOLFSSL_OLD_FIPS */
2606
2607 len = err = wc_EccKeyDerSize(key->eckey, include_pub);
2608 if (err == ECC_PRIVATEONLY_E && include_pub) {
2609 if (crypto_ec_key_gen_public_key(key) != 0) {
2610 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2611 return NULL;
2612 }
2613 len = err = wc_EccKeyDerSize(key->eckey, include_pub);
2614 }
2615 if (err <= 0) {
2616 /* Exception for BAD_FUNC_ARG because higher levels blindly call
2617 * this function to determine if this is a private key or not.
2618 * BAD_FUNC_ARG most probably means that key->eckey is a public
2619 * key not private. */
2620 if (err != BAD_FUNC_ARG)
2621 LOG_WOLF_ERROR_FUNC(wc_EccKeyDerSize, err);
2622 return NULL;
2623 }
2624
2625 ret = wpabuf_alloc(len);
2626 if (!ret) {
2627 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2628 return NULL;
2629 }
2630
2631 if (include_pub)
2632 err = wc_EccKeyToDer(key->eckey, wpabuf_put(ret, len), len);
2633 else
2634 err = wc_EccPrivateKeyToDer(key->eckey, wpabuf_put(ret, len),
2635 len);
2636
2637 if (err != len) {
2638 LOG_WOLF_ERROR_VA("%s failed with err: %d", include_pub ?
2639 "wc_EccKeyToDer" : "wc_EccPrivateKeyToDer",
2640 err);
2641 wpabuf_free(ret);
2642 ret = NULL;
2643 }
2644
2645 return ret;
2646 }
2647
2648
crypto_ec_key_get_pubkey_point(struct crypto_ec_key * key,int prefix)2649 struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
2650 int prefix)
2651 {
2652 int err;
2653 word32 len = 0;
2654 struct wpabuf *ret = NULL;
2655
2656 if (!key || !key->eckey) {
2657 LOG_INVALID_PARAMETERS();
2658 return NULL;
2659 }
2660
2661 err = wc_ecc_export_x963(key->eckey, NULL, &len);
2662 if (err != LENGTH_ONLY_E) {
2663 LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2664 goto fail;
2665 }
2666
2667 ret = wpabuf_alloc(len);
2668 if (!ret) {
2669 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2670 goto fail;
2671 }
2672
2673 err = wc_ecc_export_x963(key->eckey, wpabuf_mhead(ret), &len);
2674 if (err == ECC_PRIVATEONLY_E) {
2675 if (crypto_ec_key_gen_public_key(key) != 0) {
2676 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2677 goto fail;
2678 }
2679 err = wc_ecc_export_x963(key->eckey, wpabuf_mhead(ret), &len);
2680 }
2681 if (err != MP_OKAY) {
2682 LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2683 goto fail;
2684 }
2685
2686 if (!prefix)
2687 os_memmove(wpabuf_mhead(ret), wpabuf_mhead_u8(ret) + 1,
2688 (size_t)--len);
2689 wpabuf_put(ret, len);
2690
2691 return ret;
2692
2693 fail:
2694 wpabuf_free(ret);
2695 return NULL;
2696 }
2697
2698
crypto_ec_key_set_pub(int group,const u8 * x,const u8 * y,size_t len)2699 struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
2700 const u8 *y, size_t len)
2701 {
2702 struct crypto_ec_key *ret = NULL;
2703 int curve_id = crypto_ec_group_2_id(group);
2704 int err;
2705
2706 if (!x || !y || len == 0 || curve_id == ECC_CURVE_INVALID ||
2707 wc_ecc_get_curve_size_from_id(curve_id) != (int) len) {
2708 LOG_INVALID_PARAMETERS();
2709 return NULL;
2710 }
2711
2712 ret = crypto_ec_key_init();
2713 if (!ret) {
2714 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2715 return NULL;
2716 }
2717
2718 /* Cast necessary for FIPS API */
2719 err = wc_ecc_import_unsigned(ret->eckey, (u8 *) x, (u8 *) y, NULL,
2720 curve_id);
2721 if (err != MP_OKAY) {
2722 LOG_WOLF_ERROR_FUNC(wc_ecc_import_unsigned, err);
2723 crypto_ec_key_deinit(ret);
2724 return NULL;
2725 }
2726
2727 return ret;
2728 }
2729
2730
crypto_ec_key_cmp(struct crypto_ec_key * key1,struct crypto_ec_key * key2)2731 int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
2732 {
2733 int ret;
2734 struct wpabuf *key1_buf = crypto_ec_key_get_subject_public_key(key1);
2735 struct wpabuf *key2_buf = crypto_ec_key_get_subject_public_key(key2);
2736
2737 if ((key1 && !key1_buf) || (key2 && !key2_buf)) {
2738 LOG_WOLF_ERROR("crypto_ec_key_get_subject_public_key failed");
2739 return -1;
2740 }
2741
2742 ret = wpabuf_cmp(key1_buf, key2_buf);
2743 if (ret != 0)
2744 ret = -1; /* Default to -1 for different keys */
2745
2746 wpabuf_clear_free(key1_buf);
2747 wpabuf_clear_free(key2_buf);
2748 return ret;
2749 }
2750
2751
2752 /* wolfSSL doesn't have a pretty print function for keys so just print out the
2753 * PEM of the private key. */
crypto_ec_key_debug_print(const struct crypto_ec_key * key,const char * title)2754 void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
2755 const char *title)
2756 {
2757 struct wpabuf * key_buf;
2758 struct wpabuf * out = NULL;
2759 int err;
2760 int pem_len;
2761
2762 if (!key || !key->eckey) {
2763 LOG_INVALID_PARAMETERS();
2764 return;
2765 }
2766
2767 if (key->eckey->type == ECC_PUBLICKEY)
2768 key_buf = crypto_ec_key_get_subject_public_key(
2769 (struct crypto_ec_key *) key);
2770 else
2771 key_buf = crypto_ec_key_get_ecprivate_key(
2772 (struct crypto_ec_key *) key, 1);
2773
2774 if (!key_buf) {
2775 LOG_WOLF_ERROR_VA("%s has returned NULL",
2776 key->eckey->type == ECC_PUBLICKEY ?
2777 "crypto_ec_key_get_subject_public_key" :
2778 "crypto_ec_key_get_ecprivate_key");
2779 goto fail;
2780 }
2781
2782 if (!title)
2783 title = "";
2784
2785 err = wc_DerToPem(wpabuf_head(key_buf), wpabuf_len(key_buf), NULL, 0,
2786 ECC_TYPE);
2787 if (err <= 0) {
2788 LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
2789 goto fail;
2790 }
2791 pem_len = err;
2792
2793 out = wpabuf_alloc(pem_len + 1);
2794 if (!out) {
2795 LOG_WOLF_ERROR_FUNC_NULL(wc_DerToPem);
2796 goto fail;
2797 }
2798
2799 err = wc_DerToPem(wpabuf_head(key_buf), wpabuf_len(key_buf),
2800 wpabuf_mhead(out), pem_len, ECC_TYPE);
2801 if (err <= 0) {
2802 LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
2803 goto fail;
2804 }
2805
2806 wpabuf_mhead_u8(out)[err] = '\0';
2807 wpabuf_put(out, err + 1);
2808 wpa_printf(MSG_DEBUG, "%s:\n%s", title,
2809 (const char *) wpabuf_head(out));
2810
2811 fail:
2812 wpabuf_clear_free(key_buf);
2813 wpabuf_clear_free(out);
2814 }
2815
2816
crypto_ec_point_debug_print(const struct crypto_ec * e,const struct crypto_ec_point * p,const char * title)2817 void crypto_ec_point_debug_print(const struct crypto_ec *e,
2818 const struct crypto_ec_point *p,
2819 const char *title)
2820 {
2821 u8 x[ECC_MAXSIZE];
2822 u8 y[ECC_MAXSIZE];
2823 int coord_size;
2824 int err;
2825
2826 if (!p || !e) {
2827 LOG_INVALID_PARAMETERS();
2828 return;
2829 }
2830
2831 coord_size = e->key->dp->size;
2832
2833 if (!title)
2834 title = "";
2835
2836 err = crypto_ec_point_to_bin((struct crypto_ec *)e, p, x, y);
2837 if (err != 0) {
2838 LOG_WOLF_ERROR_FUNC(crypto_ec_point_to_bin, err);
2839 return;
2840 }
2841
2842 wpa_hexdump(MSG_DEBUG, title, x, coord_size);
2843 wpa_hexdump(MSG_DEBUG, title, y, coord_size);
2844 }
2845
2846
crypto_ec_key_gen(int group)2847 struct crypto_ec_key * crypto_ec_key_gen(int group)
2848 {
2849 int curve_id = crypto_ec_group_2_id(group);
2850 int err;
2851 struct crypto_ec_key * ret = NULL;
2852
2853 if (curve_id == ECC_CURVE_INVALID) {
2854 LOG_INVALID_PARAMETERS();
2855 return NULL;
2856 }
2857
2858 ret = crypto_ec_key_init();
2859 if (!ret) {
2860 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2861 return NULL;
2862 }
2863
2864 if (!crypto_ec_key_init_rng(ret)) {
2865 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2866 goto fail;
2867 }
2868
2869 err = wc_ecc_make_key_ex(ret->rng, 0, ret->eckey, curve_id);
2870 if (err != MP_OKAY) {
2871 LOG_WOLF_ERROR_FUNC(wc_ecc_make_key_ex, err);
2872 goto fail;
2873 }
2874
2875 return ret;
2876 fail:
2877 crypto_ec_key_deinit(ret);
2878 return NULL;
2879 }
2880
2881
crypto_ec_key_verify_signature_r_s(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * r,size_t r_len,const u8 * s,size_t s_len)2882 int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
2883 const u8 *data, size_t len,
2884 const u8 *r, size_t r_len,
2885 const u8 *s, size_t s_len)
2886 {
2887 int err;
2888 u8 sig[ECC_MAX_SIG_SIZE];
2889 word32 sig_len = ECC_MAX_SIG_SIZE;
2890
2891 if (!key || !key->eckey || !data || !len || !r || !r_len ||
2892 !s || !s_len) {
2893 LOG_INVALID_PARAMETERS();
2894 return -1;
2895 }
2896
2897 err = wc_ecc_rs_raw_to_sig(r, r_len, s, s_len, sig, &sig_len);
2898 if (err != MP_OKAY) {
2899 LOG_WOLF_ERROR_FUNC(wc_ecc_rs_raw_to_sig, err);
2900 return -1;
2901 }
2902
2903 return crypto_ec_key_verify_signature(key, data, len, sig, sig_len);
2904 }
2905
2906
crypto_ec_key_get_public_key(struct crypto_ec_key * key)2907 struct crypto_ec_point * crypto_ec_key_get_public_key(struct crypto_ec_key *key)
2908 {
2909 ecc_point *point = NULL;
2910 int err;
2911 u8 *der = NULL;
2912 word32 der_len = 0;
2913
2914 if (!key || !key->eckey || !key->eckey->dp) {
2915 LOG_INVALID_PARAMETERS();
2916 goto fail;
2917 }
2918
2919 err = wc_ecc_export_x963(key->eckey, NULL, &der_len);
2920 if (err != LENGTH_ONLY_E) {
2921 LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2922 goto fail;
2923 }
2924
2925 der = os_malloc(der_len);
2926 if (!der) {
2927 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
2928 goto fail;
2929 }
2930
2931 err = wc_ecc_export_x963(key->eckey, der, &der_len);
2932 if (err == ECC_PRIVATEONLY_E) {
2933 if (crypto_ec_key_gen_public_key(key) != 0) {
2934 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2935 goto fail;
2936 }
2937 err = wc_ecc_export_x963(key->eckey, der, &der_len);
2938 }
2939 if (err != MP_OKAY) {
2940 LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2941 goto fail;
2942 }
2943
2944 point = wc_ecc_new_point();
2945 if (!point) {
2946 LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
2947 goto fail;
2948 }
2949
2950 err = wc_ecc_import_point_der(der, der_len, key->eckey->idx, point);
2951 if (err != MP_OKAY) {
2952 LOG_WOLF_ERROR_FUNC(wc_ecc_import_point_der, err);
2953 goto fail;
2954 }
2955
2956 os_free(der);
2957 return (struct crypto_ec_point *) point;
2958
2959 fail:
2960 os_free(der);
2961 if (point)
2962 wc_ecc_del_point(point);
2963 return NULL;
2964 }
2965
2966
crypto_ec_key_get_private_key(struct crypto_ec_key * key)2967 struct crypto_bignum * crypto_ec_key_get_private_key(struct crypto_ec_key *key)
2968 {
2969 u8 priv[ECC_MAXSIZE];
2970 word32 priv_len = ECC_MAXSIZE;
2971 #ifdef WOLFSSL_OLD_FIPS
2972 /* Needed to be compliant with the old API */
2973 u8 qx[ECC_MAXSIZE];
2974 word32 qx_len = ECC_MAXSIZE;
2975 u8 qy[ECC_MAXSIZE];
2976 word32 qy_len = ECC_MAXSIZE;
2977 #endif /* WOLFSSL_OLD_FIPS */
2978 struct crypto_bignum *ret = NULL;
2979 int err;
2980
2981 if (!key || !key->eckey) {
2982 LOG_INVALID_PARAMETERS();
2983 return NULL;
2984 }
2985
2986 #ifndef WOLFSSL_OLD_FIPS
2987 err = wc_ecc_export_private_raw(key->eckey, NULL, NULL, NULL, NULL,
2988 priv, &priv_len);
2989 #else /* WOLFSSL_OLD_FIPS */
2990 err = wc_ecc_export_private_raw(key->eckey, qx, &qx_len, qy, &qy_len,
2991 priv, &priv_len);
2992 #endif /* WOLFSSL_OLD_FIPS */
2993 if (err != MP_OKAY) {
2994 LOG_WOLF_ERROR_FUNC(wc_ecc_export_private_raw, err);
2995 return NULL;
2996 }
2997
2998 ret = crypto_bignum_init_set(priv, priv_len);
2999 forced_memzero(priv, priv_len);
3000 return ret;
3001 }
3002
3003
crypto_ec_key_sign_r_s(struct crypto_ec_key * key,const u8 * data,size_t len)3004 struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
3005 const u8 *data, size_t len)
3006 {
3007 int err;
3008 u8 success = 0;
3009 mp_int r;
3010 mp_int s;
3011 u8 rs_init = 0;
3012 int sz;
3013 struct wpabuf * ret = NULL;
3014
3015 if (!key || !key->eckey || !key->eckey->dp || !data || !len) {
3016 LOG_INVALID_PARAMETERS();
3017 return NULL;
3018 }
3019
3020 sz = key->eckey->dp->size;
3021
3022 if (!crypto_ec_key_init_rng(key)) {
3023 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
3024 goto fail;
3025 }
3026
3027 err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL);
3028 if (err != MP_OKAY) {
3029 LOG_WOLF_ERROR_FUNC(mp_init_multi, err);
3030 goto fail;
3031 }
3032 rs_init = 1;
3033
3034 err = wc_ecc_sign_hash_ex(data, len, key->rng, key->eckey, &r, &s);
3035 if (err != MP_OKAY) {
3036 LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash_ex, err);
3037 goto fail;
3038 }
3039
3040 if (mp_unsigned_bin_size(&r) > sz || mp_unsigned_bin_size(&s) > sz) {
3041 LOG_WOLF_ERROR_VA("Unexpected size of r or s (%d %d %d)", sz,
3042 mp_unsigned_bin_size(&r),
3043 mp_unsigned_bin_size(&s));
3044 goto fail;
3045 }
3046
3047 ret = wpabuf_alloc(2 * sz);
3048 if (!ret) {
3049 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3050 goto fail;
3051 }
3052
3053 err = mp_to_unsigned_bin_len(&r, wpabuf_put(ret, sz), sz);
3054 if (err == MP_OKAY)
3055 err = mp_to_unsigned_bin_len(&s, wpabuf_put(ret, sz), sz);
3056 if (err != MP_OKAY) {
3057 LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash_ex, err);
3058 goto fail;
3059 }
3060
3061 success = 1;
3062 fail:
3063 if (rs_init) {
3064 mp_free(&r);
3065 mp_free(&s);
3066 }
3067 if (!success) {
3068 wpabuf_free(ret);
3069 ret = NULL;
3070 }
3071
3072 return ret;
3073 }
3074
3075
3076 struct crypto_ec_key *
crypto_ec_key_set_pub_point(struct crypto_ec * e,const struct crypto_ec_point * pub)3077 crypto_ec_key_set_pub_point(struct crypto_ec *e,
3078 const struct crypto_ec_point *pub)
3079 {
3080 struct crypto_ec_key *ret = NULL;
3081 int err;
3082 byte *buf = NULL;
3083 word32 buf_len = 0;
3084
3085 if (!e || !pub) {
3086 LOG_INVALID_PARAMETERS();
3087 return NULL;
3088 }
3089
3090 /* Export to DER to not mess with wolfSSL internals */
3091 err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(e->curve_id),
3092 (ecc_point *) pub, NULL, &buf_len);
3093 if (err != LENGTH_ONLY_E || !buf_len) {
3094 LOG_WOLF_ERROR_FUNC(wc_ecc_export_point_der, err);
3095 goto fail;
3096 }
3097
3098 buf = os_malloc(buf_len);
3099 if (!buf) {
3100 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3101 goto fail;
3102 }
3103
3104 err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(e->curve_id),
3105 (ecc_point *) pub, buf, &buf_len);
3106 if (err != MP_OKAY) {
3107 LOG_WOLF_ERROR_FUNC(wc_ecc_export_point_der, err);
3108 goto fail;
3109 }
3110
3111 ret = crypto_ec_key_init();
3112 if (!ret) {
3113 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
3114 goto fail;
3115 }
3116
3117 err = wc_ecc_import_x963_ex(buf, buf_len, ret->eckey, e->curve_id);
3118 if (err != MP_OKAY) {
3119 LOG_WOLF_ERROR_FUNC(wc_ecc_import_x963_ex, err);
3120 goto fail;
3121 }
3122
3123 os_free(buf);
3124 return ret;
3125
3126 fail:
3127 os_free(buf);
3128 crypto_ec_key_deinit(ret);
3129 return NULL;
3130 }
3131
3132
crypto_pkcs7_get_certificates(const struct wpabuf * pkcs7)3133 struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
3134 {
3135 PKCS7 *p7 = NULL;
3136 struct wpabuf *ret = NULL;
3137 int err = 0;
3138 int total_sz = 0;
3139 int i;
3140
3141 if (!pkcs7) {
3142 LOG_INVALID_PARAMETERS();
3143 return NULL;
3144 }
3145
3146 p7 = wc_PKCS7_New(NULL, INVALID_DEVID);
3147 if (!p7) {
3148 LOG_WOLF_ERROR_FUNC_NULL(wc_PKCS7_New);
3149 return NULL;
3150 }
3151
3152 err = wc_PKCS7_VerifySignedData(p7, (byte *) wpabuf_head(pkcs7),
3153 wpabuf_len(pkcs7));
3154 if (err != 0) {
3155 LOG_WOLF_ERROR_FUNC(wc_PKCS7_VerifySignedData, err);
3156 wc_PKCS7_Free(p7);
3157 goto fail;
3158 }
3159
3160 /* Need to access p7 members directly */
3161 for (i = 0; i < MAX_PKCS7_CERTS; i++) {
3162 if (p7->certSz[i] == 0)
3163 continue;
3164 err = wc_DerToPem(p7->cert[i], p7->certSz[i], NULL, 0,
3165 CERT_TYPE);
3166 if (err > 0) {
3167 total_sz += err;
3168 } else {
3169 LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
3170 goto fail;
3171 }
3172 }
3173
3174 if (total_sz == 0) {
3175 LOG_WOLF_ERROR("No certificates found in PKCS7 input");
3176 goto fail;
3177 }
3178
3179 ret = wpabuf_alloc(total_sz);
3180 if (!ret) {
3181 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3182 goto fail;
3183 }
3184
3185 /* Need to access p7 members directly */
3186 for (i = 0; i < MAX_PKCS7_CERTS; i++) {
3187 if (p7->certSz[i] == 0)
3188 continue;
3189 /* Not using wpabuf_put() here so that wpabuf_overflow() isn't
3190 * called in case of a size mismatch. wc_DerToPem() checks if
3191 * the output is large enough internally. */
3192 err = wc_DerToPem(p7->cert[i], p7->certSz[i],
3193 wpabuf_mhead_u8(ret) + wpabuf_len(ret),
3194 wpabuf_tailroom(ret),
3195 CERT_TYPE);
3196 if (err > 0) {
3197 wpabuf_put(ret, err);
3198 } else {
3199 LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
3200 wpabuf_free(ret);
3201 ret = NULL;
3202 goto fail;
3203 }
3204 }
3205
3206 fail:
3207 if (p7)
3208 wc_PKCS7_Free(p7);
3209 return ret;
3210 }
3211
3212
3213 /* BEGIN Certificate Signing Request (CSR) APIs */
3214
3215 enum cert_type {
3216 cert_type_none = 0,
3217 cert_type_decoded_cert,
3218 cert_type_cert,
3219 };
3220
3221 struct crypto_csr {
3222 union {
3223 /* For parsed csr should be read-only for higher levels */
3224 DecodedCert dc;
3225 Cert c; /* For generating a csr */
3226 } req;
3227 enum cert_type type;
3228 struct crypto_ec_key *pubkey;
3229 };
3230
3231
3232 /* Helper function to make sure that the correct type is initialized */
crypto_csr_init_type(struct crypto_csr * csr,enum cert_type type,const byte * source,word32 in_sz)3233 static void crypto_csr_init_type(struct crypto_csr *csr, enum cert_type type,
3234 const byte *source, word32 in_sz)
3235 {
3236 int err;
3237
3238 if (csr->type == type)
3239 return; /* Already correct type */
3240
3241 switch (csr->type) {
3242 case cert_type_decoded_cert:
3243 wc_FreeDecodedCert(&csr->req.dc);
3244 break;
3245 case cert_type_cert:
3246 #ifdef WOLFSSL_CERT_GEN_CACHE
3247 wc_SetCert_Free(&csr->req.c);
3248 #endif /* WOLFSSL_CERT_GEN_CACHE */
3249 break;
3250 case cert_type_none:
3251 break;
3252 }
3253
3254 switch (type) {
3255 case cert_type_decoded_cert:
3256 wc_InitDecodedCert(&csr->req.dc, source, in_sz, NULL);
3257 break;
3258 case cert_type_cert:
3259 err = wc_InitCert(&csr->req.c);
3260 if (err != 0)
3261 LOG_WOLF_ERROR_FUNC(wc_InitCert, err);
3262 break;
3263 case cert_type_none:
3264 break;
3265 }
3266
3267 csr->type = type;
3268 }
3269
3270
crypto_csr_init(void)3271 struct crypto_csr * crypto_csr_init(void)
3272 {
3273 struct crypto_csr *ret = os_malloc(sizeof(struct crypto_csr));
3274
3275 if (!ret) {
3276 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3277 return NULL;
3278 }
3279
3280 ret->type = cert_type_none;
3281 crypto_csr_init_type(ret, cert_type_cert, NULL, 0);
3282 ret->pubkey = NULL;
3283
3284 return ret;
3285 }
3286
3287
crypto_csr_deinit(struct crypto_csr * csr)3288 void crypto_csr_deinit(struct crypto_csr *csr)
3289 {
3290 if (csr) {
3291 crypto_csr_init_type(csr, cert_type_none, NULL, 0);
3292 crypto_ec_key_deinit(csr->pubkey);
3293 os_free(csr);
3294 }
3295 }
3296
3297
crypto_csr_set_ec_public_key(struct crypto_csr * csr,struct crypto_ec_key * key)3298 int crypto_csr_set_ec_public_key(struct crypto_csr *csr,
3299 struct crypto_ec_key *key)
3300 {
3301 struct wpabuf *der = NULL;
3302
3303 if (!csr || !key || !key->eckey) {
3304 LOG_INVALID_PARAMETERS();
3305 return -1;
3306 }
3307
3308 if (csr->pubkey) {
3309 crypto_ec_key_deinit(csr->pubkey);
3310 csr->pubkey = NULL;
3311 }
3312
3313 /* Create copy of key to mitigate use-after-free errors */
3314 der = crypto_ec_key_get_subject_public_key(key);
3315 if (!der) {
3316 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_get_subject_public_key);
3317 return -1;
3318 }
3319
3320 csr->pubkey = crypto_ec_key_parse_pub(wpabuf_head(der),
3321 wpabuf_len(der));
3322 wpabuf_free(der);
3323 if (!csr->pubkey) {
3324 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_parse_pub);
3325 return -1;
3326 }
3327
3328 return 0;
3329 }
3330
3331
crypto_csr_set_name(struct crypto_csr * csr,enum crypto_csr_name type,const char * name)3332 int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
3333 const char *name)
3334 {
3335 int name_len;
3336 char *dest;
3337
3338 if (!csr || !name) {
3339 LOG_INVALID_PARAMETERS();
3340 return -1;
3341 }
3342
3343 if (csr->type != cert_type_cert) {
3344 LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3345 return -1;
3346 }
3347
3348 name_len = os_strlen(name);
3349 if (name_len >= CTC_NAME_SIZE) {
3350 LOG_WOLF_ERROR("name input too long");
3351 return -1;
3352 }
3353
3354 switch (type) {
3355 case CSR_NAME_CN:
3356 dest = csr->req.c.subject.commonName;
3357 break;
3358 case CSR_NAME_SN:
3359 dest = csr->req.c.subject.sur;
3360 break;
3361 case CSR_NAME_C:
3362 dest = csr->req.c.subject.country;
3363 break;
3364 case CSR_NAME_O:
3365 dest = csr->req.c.subject.org;
3366 break;
3367 case CSR_NAME_OU:
3368 dest = csr->req.c.subject.unit;
3369 break;
3370 default:
3371 LOG_INVALID_PARAMETERS();
3372 return -1;
3373 }
3374
3375 os_memcpy(dest, name, name_len);
3376 dest[name_len] = '\0';
3377
3378 return 0;
3379 }
3380
3381
crypto_csr_set_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,int attr_type,const u8 * value,size_t len)3382 int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
3383 int attr_type, const u8 *value, size_t len)
3384 {
3385 if (!csr || attr_type != ASN1_TAG_UTF8STRING || !value ||
3386 len >= CTC_NAME_SIZE) {
3387 LOG_INVALID_PARAMETERS();
3388 return -1;
3389 }
3390
3391 if (csr->type != cert_type_cert) {
3392 LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3393 return -1;
3394 }
3395
3396 switch (attr) {
3397 case CSR_ATTR_CHALLENGE_PASSWORD:
3398 os_memcpy(csr->req.c.challengePw, value, len);
3399 csr->req.c.challengePw[len] = '\0';
3400 break;
3401 default:
3402 return -1;
3403 }
3404
3405 return 0;
3406 }
3407
3408
crypto_csr_get_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,size_t * len,int * type)3409 const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
3410 enum crypto_csr_attr attr,
3411 size_t *len, int *type)
3412 {
3413 if (!csr || !len || !type) {
3414 LOG_INVALID_PARAMETERS();
3415 return NULL;;
3416 }
3417
3418 switch (attr) {
3419 case CSR_ATTR_CHALLENGE_PASSWORD:
3420 switch (csr->type) {
3421 case cert_type_decoded_cert:
3422 *type = ASN1_TAG_UTF8STRING;
3423 *len = csr->req.dc.cPwdLen;
3424 return (const u8 *) csr->req.dc.cPwd;
3425 case cert_type_cert:
3426 *type = ASN1_TAG_UTF8STRING;
3427 *len = os_strlen(csr->req.c.challengePw);
3428 return (const u8 *) csr->req.c.challengePw;
3429 case cert_type_none:
3430 return NULL;
3431 }
3432 break;
3433 }
3434 return NULL;
3435 }
3436
3437
crypto_csr_sign(struct crypto_csr * csr,struct crypto_ec_key * key,enum crypto_hash_alg algo)3438 struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
3439 struct crypto_ec_key *key,
3440 enum crypto_hash_alg algo)
3441 {
3442 int err;
3443 int len;
3444 u8 *buf = NULL;
3445 int buf_len;
3446 struct wpabuf *ret = NULL;
3447
3448 if (!csr || !key || !key->eckey) {
3449 LOG_INVALID_PARAMETERS();
3450 return NULL;
3451 }
3452
3453 if (csr->type != cert_type_cert) {
3454 LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3455 return NULL;
3456 }
3457
3458 if (!crypto_ec_key_init_rng(key)) {
3459 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
3460 return NULL;
3461 }
3462
3463 switch (algo) {
3464 case CRYPTO_HASH_ALG_SHA256:
3465 csr->req.c.sigType = CTC_SHA256wECDSA;
3466 break;
3467 case CRYPTO_HASH_ALG_SHA384:
3468 csr->req.c.sigType = CTC_SHA384wECDSA;
3469 break;
3470 case CRYPTO_HASH_ALG_SHA512:
3471 csr->req.c.sigType = CTC_SHA512wECDSA;
3472 break;
3473 default:
3474 LOG_INVALID_PARAMETERS();
3475 return NULL;
3476 }
3477
3478 /* Pass in large value that is guaranteed to be larger than the
3479 * necessary buffer */
3480 err = wc_MakeCertReq(&csr->req.c, NULL, 100000, NULL,
3481 csr->pubkey->eckey);
3482 if (err <= 0) {
3483 LOG_WOLF_ERROR_FUNC(wc_MakeCertReq, err);
3484 goto fail;
3485 }
3486 len = err;
3487
3488 buf_len = len + MAX_SEQ_SZ * 2 + MAX_ENCODED_SIG_SZ;
3489 buf = os_malloc(buf_len);
3490 if (!buf) {
3491 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3492 goto fail;
3493 }
3494
3495 err = wc_MakeCertReq(&csr->req.c, buf, buf_len, NULL,
3496 csr->pubkey->eckey);
3497 if (err <= 0) {
3498 LOG_WOLF_ERROR_FUNC(wc_MakeCertReq, err);
3499 goto fail;
3500 }
3501 len = err;
3502
3503 err = wc_SignCert(len, csr->req.c.sigType, buf, buf_len, NULL,
3504 key->eckey, key->rng);
3505 if (err <= 0) {
3506 LOG_WOLF_ERROR_FUNC(wc_SignCert, err);
3507 goto fail;
3508 }
3509 len = err;
3510
3511 ret = wpabuf_alloc_copy(buf, len);
3512 if (!ret) {
3513 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc_copy);
3514 goto fail;
3515 }
3516
3517 fail:
3518 os_free(buf);
3519 return ret;
3520 }
3521
3522
crypto_csr_verify(const struct wpabuf * req)3523 struct crypto_csr * crypto_csr_verify(const struct wpabuf *req)
3524 {
3525 struct crypto_csr *csr = NULL;
3526 int err;
3527
3528 if (!req) {
3529 LOG_INVALID_PARAMETERS();
3530 return NULL;
3531 }
3532
3533 csr = crypto_csr_init();
3534 if (!csr) {
3535 LOG_WOLF_ERROR_FUNC_NULL(crypto_csr_init);
3536 goto fail;
3537 }
3538
3539 crypto_csr_init_type(csr, cert_type_decoded_cert,
3540 wpabuf_head(req), wpabuf_len(req));
3541 err = wc_ParseCert(&csr->req.dc, CERTREQ_TYPE, VERIFY, NULL);
3542 if (err != 0) {
3543 LOG_WOLF_ERROR_FUNC(wc_ParseCert, err);
3544 goto fail;
3545 }
3546
3547 return csr;
3548 fail:
3549 crypto_csr_deinit(csr);
3550 return NULL;
3551 }
3552
3553 /* END Certificate Signing Request (CSR) APIs */
3554
3555 #endif /* CONFIG_DPP */
3556
3557
crypto_unload(void)3558 void crypto_unload(void)
3559 {
3560 }
3561