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_sqrtmod(const struct crypto_bignum * a,const struct crypto_bignum * b,struct crypto_bignum * c)1528 int crypto_bignum_sqrtmod(const struct crypto_bignum *a,
1529 const struct crypto_bignum *b,
1530 struct crypto_bignum *c)
1531 {
1532 /* TODO */
1533 return -1;
1534 }
1535
1536
crypto_bignum_rshift(const struct crypto_bignum * a,int n,struct crypto_bignum * r)1537 int crypto_bignum_rshift(const struct crypto_bignum *a, int n,
1538 struct crypto_bignum *r)
1539 {
1540 if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY)
1541 return -1;
1542 mp_rshb((mp_int *) r, n);
1543 return 0;
1544 }
1545
1546
crypto_bignum_cmp(const struct crypto_bignum * a,const struct crypto_bignum * b)1547 int crypto_bignum_cmp(const struct crypto_bignum *a,
1548 const struct crypto_bignum *b)
1549 {
1550 return mp_cmp((mp_int *) a, (mp_int *) b);
1551 }
1552
1553
crypto_bignum_is_zero(const struct crypto_bignum * a)1554 int crypto_bignum_is_zero(const struct crypto_bignum *a)
1555 {
1556 return mp_iszero((mp_int *) a);
1557 }
1558
1559
crypto_bignum_is_one(const struct crypto_bignum * a)1560 int crypto_bignum_is_one(const struct crypto_bignum *a)
1561 {
1562 return mp_isone((const mp_int *) a);
1563 }
1564
crypto_bignum_is_odd(const struct crypto_bignum * a)1565 int crypto_bignum_is_odd(const struct crypto_bignum *a)
1566 {
1567 return mp_isodd((mp_int *) a);
1568 }
1569
1570
crypto_bignum_legendre(const struct crypto_bignum * a,const struct crypto_bignum * p)1571 int crypto_bignum_legendre(const struct crypto_bignum *a,
1572 const struct crypto_bignum *p)
1573 {
1574 mp_int t;
1575 int ret;
1576 int res = -2;
1577
1578 if (TEST_FAIL())
1579 return -2;
1580
1581 if (mp_init(&t) != MP_OKAY)
1582 return -2;
1583
1584 /* t = (p-1) / 2 */
1585 ret = mp_sub_d((mp_int *) p, 1, &t);
1586 if (ret == MP_OKAY)
1587 mp_rshb(&t, 1);
1588 if (ret == MP_OKAY)
1589 ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t);
1590 if (ret == MP_OKAY) {
1591 if (mp_isone(&t))
1592 res = 1;
1593 else if (mp_iszero(&t))
1594 res = 0;
1595 else
1596 res = -1;
1597 }
1598
1599 mp_clear(&t);
1600 return res;
1601 }
1602
1603
1604 #ifdef CONFIG_ECC
1605
crypto_ec_group_2_id(int group)1606 static int crypto_ec_group_2_id(int group)
1607 {
1608 switch (group) {
1609 case 19:
1610 return ECC_SECP256R1;
1611 case 20:
1612 return ECC_SECP384R1;
1613 case 21:
1614 return ECC_SECP521R1;
1615 case 25:
1616 return ECC_SECP192R1;
1617 case 26:
1618 return ECC_SECP224R1;
1619 #ifdef HAVE_ECC_BRAINPOOL
1620 case 27:
1621 return ECC_BRAINPOOLP224R1;
1622 case 28:
1623 return ECC_BRAINPOOLP256R1;
1624 case 29:
1625 return ECC_BRAINPOOLP384R1;
1626 case 30:
1627 return ECC_BRAINPOOLP512R1;
1628 #endif /* HAVE_ECC_BRAINPOOL */
1629 default:
1630 LOG_WOLF_ERROR_VA("Unsupported curve (id=%d) in EC key", group);
1631 return ECC_CURVE_INVALID;
1632 }
1633 }
1634
1635
1636 int ecc_map(ecc_point *, mp_int *, mp_digit);
1637 int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
1638 mp_int *a, mp_int *modulus, mp_digit mp);
1639
1640 struct crypto_ec {
1641 ecc_key *key;
1642 #ifdef CONFIG_DPP
1643 ecc_point *g; /* Only used in DPP for now */
1644 #endif /* CONFIG_DPP */
1645 mp_int a;
1646 mp_int prime;
1647 mp_int order;
1648 mp_digit mont_b;
1649 mp_int b;
1650 int curve_id;
1651 bool own_key; /* Should we free the `key` */
1652 };
1653
1654
crypto_ec_init(int group)1655 struct crypto_ec * crypto_ec_init(int group)
1656 {
1657 int built = 0;
1658 struct crypto_ec *e;
1659 int curve_id = crypto_ec_group_2_id(group);
1660 int err;
1661
1662 if (curve_id == ECC_CURVE_INVALID) {
1663 LOG_INVALID_PARAMETERS();
1664 return NULL;
1665 }
1666
1667 e = os_zalloc(sizeof(*e));
1668 if (!e) {
1669 LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
1670 return NULL;
1671 }
1672
1673 e->curve_id = curve_id;
1674 e->own_key = true;
1675 e->key = ecc_key_init();
1676 if (!e->key) {
1677 LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init);
1678 goto done;
1679 }
1680
1681 err = wc_ecc_set_curve(e->key, 0, curve_id);
1682 if (err != 0) {
1683 LOG_WOLF_ERROR_FUNC(wc_ecc_set_curve, err);
1684 goto done;
1685 }
1686 #ifdef CONFIG_DPP
1687 e->g = wc_ecc_new_point();
1688 if (!e->g) {
1689 LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
1690 goto done;
1691 }
1692 #ifdef CONFIG_FIPS
1693 /* Setup generator manually in FIPS mode */
1694 if (!e->key->dp) {
1695 LOG_WOLF_ERROR_FUNC_NULL(e->key->dp);
1696 goto done;
1697 }
1698 err = mp_read_radix(e->g->x, e->key->dp->Gx, MP_RADIX_HEX);
1699 if (err != MP_OKAY) {
1700 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1701 goto done;
1702 }
1703 err = mp_read_radix(e->g->y, e->key->dp->Gy, MP_RADIX_HEX);
1704 if (err != MP_OKAY) {
1705 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1706 goto done;
1707 }
1708 err = mp_set(e->g->z, 1);
1709 if (err != MP_OKAY) {
1710 LOG_WOLF_ERROR_FUNC(mp_set, err);
1711 goto done;
1712 }
1713 #else /* CONFIG_FIPS */
1714 err = wc_ecc_get_generator(e->g, wc_ecc_get_curve_idx(curve_id));
1715 if (err != MP_OKAY) {
1716 LOG_WOLF_ERROR_FUNC(wc_ecc_get_generator, err);
1717 goto done;
1718 }
1719 #endif /* CONFIG_FIPS */
1720 #endif /* CONFIG_DPP */
1721 err = mp_init_multi(&e->a, &e->prime, &e->order, &e->b, NULL, NULL);
1722 if (err != MP_OKAY) {
1723 LOG_WOLF_ERROR_FUNC(mp_init_multi, err);
1724 goto done;
1725 }
1726 err = mp_read_radix(&e->a, e->key->dp->Af, 16);
1727 if (err != MP_OKAY) {
1728 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1729 goto done;
1730 }
1731 err = mp_read_radix(&e->b, e->key->dp->Bf, 16);
1732 if (err != MP_OKAY) {
1733 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1734 goto done;
1735 }
1736 err = mp_read_radix(&e->prime, e->key->dp->prime, 16);
1737 if (err != MP_OKAY) {
1738 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1739 goto done;
1740 }
1741 err = mp_read_radix(&e->order, e->key->dp->order, 16);
1742 if (err != MP_OKAY) {
1743 LOG_WOLF_ERROR_FUNC(mp_read_radix, err);
1744 goto done;
1745 }
1746 err = mp_montgomery_setup(&e->prime, &e->mont_b);
1747 if (err != MP_OKAY) {
1748 LOG_WOLF_ERROR_FUNC(mp_montgomery_setup, err);
1749 goto done;
1750 }
1751
1752 built = 1;
1753 done:
1754 if (!built) {
1755 crypto_ec_deinit(e);
1756 e = NULL;
1757 }
1758 return e;
1759 }
1760
1761
crypto_ec_deinit(struct crypto_ec * e)1762 void crypto_ec_deinit(struct crypto_ec* e)
1763 {
1764 if (!e)
1765 return;
1766
1767 mp_clear(&e->b);
1768 mp_clear(&e->order);
1769 mp_clear(&e->prime);
1770 mp_clear(&e->a);
1771 #ifdef CONFIG_DPP
1772 wc_ecc_del_point(e->g);
1773 #endif /* CONFIG_DPP */
1774 if (e->own_key)
1775 ecc_key_deinit(e->key);
1776 os_free(e);
1777 }
1778
1779
crypto_ec_point_init(struct crypto_ec * e)1780 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1781 {
1782 if (TEST_FAIL())
1783 return NULL;
1784 if (!e)
1785 return NULL;
1786 return (struct crypto_ec_point *) wc_ecc_new_point();
1787 }
1788
1789
crypto_ec_prime_len(struct crypto_ec * e)1790 size_t crypto_ec_prime_len(struct crypto_ec *e)
1791 {
1792 return (mp_count_bits(&e->prime) + 7) / 8;
1793 }
1794
1795
crypto_ec_prime_len_bits(struct crypto_ec * e)1796 size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1797 {
1798 return mp_count_bits(&e->prime);
1799 }
1800
1801
crypto_ec_order_len(struct crypto_ec * e)1802 size_t crypto_ec_order_len(struct crypto_ec *e)
1803 {
1804 return (mp_count_bits(&e->order) + 7) / 8;
1805 }
1806
1807
crypto_ec_get_prime(struct crypto_ec * e)1808 const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1809 {
1810 return (const struct crypto_bignum *) &e->prime;
1811 }
1812
1813
crypto_ec_get_order(struct crypto_ec * e)1814 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1815 {
1816 return (const struct crypto_bignum *) &e->order;
1817 }
1818
1819
crypto_ec_get_a(struct crypto_ec * e)1820 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e)
1821 {
1822 return (const struct crypto_bignum *) &e->a;
1823 }
1824
1825
crypto_ec_get_b(struct crypto_ec * e)1826 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
1827 {
1828 return (const struct crypto_bignum *) &e->b;
1829 }
1830
1831
crypto_ec_point_deinit(struct crypto_ec_point * p,int clear)1832 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1833 {
1834 ecc_point *point = (ecc_point *) p;
1835
1836 if (!p)
1837 return;
1838
1839 if (clear) {
1840 #ifdef CONFIG_FIPS
1841 mp_forcezero(point->x);
1842 mp_forcezero(point->y);
1843 mp_forcezero(point->z);
1844 #else /* CONFIG_FIPS */
1845 wc_ecc_forcezero_point(point);
1846 #endif /* CONFIG_FIPS */
1847 }
1848 wc_ecc_del_point(point);
1849 }
1850
1851
1852 #ifdef CONFIG_DPP
crypto_ec_get_generator(struct crypto_ec * e)1853 const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
1854 {
1855 return (const struct crypto_ec_point *) e->g;
1856 }
1857 #endif /* CONFIG_DPP */
1858
1859
crypto_ec_point_x(struct crypto_ec * e,const struct crypto_ec_point * p,struct crypto_bignum * x)1860 int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p,
1861 struct crypto_bignum *x)
1862 {
1863 return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1;
1864 }
1865
1866
crypto_ec_point_to_bin(struct crypto_ec * e,const struct crypto_ec_point * point,u8 * x,u8 * y)1867 int crypto_ec_point_to_bin(struct crypto_ec *e,
1868 const struct crypto_ec_point *point, u8 *x, u8 *y)
1869 {
1870 ecc_point *p = (ecc_point *) point;
1871 int len;
1872 int err;
1873
1874 if (TEST_FAIL())
1875 return -1;
1876
1877 if (!mp_isone(p->z)) {
1878 err = ecc_map(p, &e->prime, e->mont_b);
1879 if (err != MP_OKAY) {
1880 LOG_WOLF_ERROR_FUNC(ecc_map, err);
1881 return -1;
1882 }
1883 }
1884
1885 len = wc_ecc_get_curve_size_from_id(e->curve_id);
1886 if (len <= 0) {
1887 LOG_WOLF_ERROR_FUNC(wc_ecc_get_curve_size_from_id, len);
1888 LOG_WOLF_ERROR_VA("wc_ecc_get_curve_size_from_id error for curve_id %d", e->curve_id);
1889 return -1;
1890 }
1891
1892 if (x) {
1893 if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x,
1894 (size_t) len, (size_t) len) <= 0) {
1895 LOG_WOLF_ERROR_FUNC(crypto_bignum_to_bin, -1);
1896 return -1;
1897 }
1898 }
1899
1900 if (y) {
1901 if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y,
1902 (size_t) len, (size_t) len) <= 0) {
1903 LOG_WOLF_ERROR_FUNC(crypto_bignum_to_bin, -1);
1904 return -1;
1905 }
1906 }
1907
1908 return 0;
1909 }
1910
1911
crypto_ec_point_from_bin(struct crypto_ec * e,const u8 * val)1912 struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1913 const u8 *val)
1914 {
1915 ecc_point *point = NULL;
1916 int loaded = 0;
1917
1918 if (TEST_FAIL())
1919 return NULL;
1920
1921 point = wc_ecc_new_point();
1922 if (!point)
1923 goto done;
1924
1925 if (mp_read_unsigned_bin(point->x, val, e->key->dp->size) != MP_OKAY)
1926 goto done;
1927 val += e->key->dp->size;
1928 if (mp_read_unsigned_bin(point->y, val, e->key->dp->size) != MP_OKAY)
1929 goto done;
1930 mp_set(point->z, 1);
1931
1932 loaded = 1;
1933 done:
1934 if (!loaded) {
1935 wc_ecc_del_point(point);
1936 point = NULL;
1937 }
1938 return (struct crypto_ec_point *) point;
1939 }
1940
1941
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)1942 int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1943 const struct crypto_ec_point *b,
1944 struct crypto_ec_point *c)
1945 {
1946 mp_int mu;
1947 ecc_point *ta = NULL, *tb = NULL;
1948 ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b;
1949 mp_int *modulus = &e->prime;
1950 int ret;
1951
1952 if (TEST_FAIL())
1953 return -1;
1954
1955 ret = mp_init(&mu);
1956 if (ret != MP_OKAY)
1957 return -1;
1958
1959 ret = mp_montgomery_calc_normalization(&mu, modulus);
1960 if (ret != MP_OKAY) {
1961 mp_clear(&mu);
1962 return -1;
1963 }
1964
1965 if (!mp_isone(&mu)) {
1966 ta = wc_ecc_new_point();
1967 if (!ta) {
1968 mp_clear(&mu);
1969 return -1;
1970 }
1971 tb = wc_ecc_new_point();
1972 if (!tb) {
1973 wc_ecc_del_point(ta);
1974 mp_clear(&mu);
1975 return -1;
1976 }
1977
1978 if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY ||
1979 mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY ||
1980 mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY ||
1981 mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY ||
1982 mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY ||
1983 mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) {
1984 ret = -1;
1985 goto end;
1986 }
1987 pa = ta;
1988 pb = tb;
1989 }
1990
1991 ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a,
1992 &e->prime, e->mont_b);
1993 if (ret != 0) {
1994 ret = -1;
1995 goto end;
1996 }
1997
1998 if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY)
1999 ret = -1;
2000 else
2001 ret = 0;
2002 end:
2003 wc_ecc_del_point(tb);
2004 wc_ecc_del_point(ta);
2005 mp_clear(&mu);
2006 return ret;
2007 }
2008
2009
crypto_ec_point_mul(struct crypto_ec * e,const struct crypto_ec_point * p,const struct crypto_bignum * b,struct crypto_ec_point * res)2010 int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
2011 const struct crypto_bignum *b,
2012 struct crypto_ec_point *res)
2013 {
2014 int ret;
2015
2016 if (TEST_FAIL())
2017 return -1;
2018
2019 ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res,
2020 &e->a, &e->prime, 1);
2021 return ret == 0 ? 0 : -1;
2022 }
2023
2024
crypto_ec_point_invert(struct crypto_ec * e,struct crypto_ec_point * p)2025 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
2026 {
2027 ecc_point *point = (ecc_point *) p;
2028
2029 if (TEST_FAIL())
2030 return -1;
2031
2032 if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY)
2033 return -1;
2034
2035 return 0;
2036 }
2037
2038
2039 struct crypto_bignum *
crypto_ec_point_compute_y_sqr(struct crypto_ec * e,const struct crypto_bignum * x)2040 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
2041 const struct crypto_bignum *x)
2042 {
2043 mp_int *y2;
2044
2045 if (TEST_FAIL())
2046 return NULL;
2047
2048 /* y^2 = x^3 + ax + b = (x^2 + a)x + b */
2049 y2 = (mp_int *) crypto_bignum_init();
2050 if (!y2 ||
2051 mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
2052 mp_addmod(y2, &e->a, &e->prime, y2) != 0 ||
2053 mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
2054 mp_addmod(y2, &e->b, &e->prime, y2) != 0) {
2055 mp_clear(y2);
2056 os_free(y2);
2057 y2 = NULL;
2058 }
2059
2060 return (struct crypto_bignum *) y2;
2061 }
2062
2063
crypto_ec_point_is_at_infinity(struct crypto_ec * e,const struct crypto_ec_point * p)2064 int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
2065 const struct crypto_ec_point *p)
2066 {
2067 return wc_ecc_point_is_at_infinity((ecc_point *) p);
2068 }
2069
2070
crypto_ec_point_is_on_curve(struct crypto_ec * e,const struct crypto_ec_point * p)2071 int crypto_ec_point_is_on_curve(struct crypto_ec *e,
2072 const struct crypto_ec_point *p)
2073 {
2074 return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) ==
2075 MP_OKAY;
2076 }
2077
2078
crypto_ec_point_cmp(const struct crypto_ec * e,const struct crypto_ec_point * a,const struct crypto_ec_point * b)2079 int crypto_ec_point_cmp(const struct crypto_ec *e,
2080 const struct crypto_ec_point *a,
2081 const struct crypto_ec_point *b)
2082 {
2083 return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
2084 }
2085
2086 struct crypto_ec_key {
2087 ecc_key *eckey;
2088 WC_RNG *rng; /* Needs to be initialized before use.
2089 * *NOT* initialized in crypto_ec_key_init */
2090 };
2091
2092
2093 struct crypto_ecdh {
2094 struct crypto_ec *ec;
2095 WC_RNG *rng;
2096 };
2097
_crypto_ecdh_init(int group)2098 static struct crypto_ecdh * _crypto_ecdh_init(int group)
2099 {
2100 struct crypto_ecdh *ecdh = NULL;
2101 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2102 int ret;
2103 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2104
2105 ecdh = os_zalloc(sizeof(*ecdh));
2106 if (!ecdh) {
2107 LOG_WOLF_ERROR_FUNC_NULL(os_zalloc);
2108 return NULL;
2109 }
2110
2111 ecdh->rng = wc_rng_init();
2112 if (!ecdh->rng) {
2113 LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
2114 goto fail;
2115 }
2116
2117 ecdh->ec = crypto_ec_init(group);
2118 if (!ecdh->ec) {
2119 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_init);
2120 goto fail;
2121 }
2122
2123 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2124 ret = wc_ecc_set_rng(ecdh->ec->key, ecdh->rng);
2125 if (ret != 0) {
2126 LOG_WOLF_ERROR_FUNC(wc_ecc_set_rng, ret);
2127 goto fail;
2128 }
2129 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2130
2131 return ecdh;
2132 fail:
2133 crypto_ecdh_deinit(ecdh);
2134 return NULL;
2135 }
2136
2137
crypto_ecdh_init(int group)2138 struct crypto_ecdh * crypto_ecdh_init(int group)
2139 {
2140 struct crypto_ecdh *ret = NULL;
2141 int err;
2142
2143 ret = _crypto_ecdh_init(group);
2144
2145 if (!ret) {
2146 LOG_WOLF_ERROR_FUNC_NULL(_crypto_ecdh_init);
2147 return NULL;
2148 }
2149
2150 err = wc_ecc_make_key_ex(ret->rng, 0, ret->ec->key,
2151 crypto_ec_group_2_id(group));
2152 if (err != MP_OKAY) {
2153 LOG_WOLF_ERROR_FUNC(wc_ecc_make_key_ex, err);
2154 crypto_ecdh_deinit(ret);
2155 ret = NULL;
2156 }
2157
2158 return ret;
2159 }
2160
2161
crypto_ecdh_init2(int group,struct crypto_ec_key * own_key)2162 struct crypto_ecdh * crypto_ecdh_init2(int group, struct crypto_ec_key *own_key)
2163 {
2164 struct crypto_ecdh *ret = NULL;
2165
2166 if (!own_key || crypto_ec_key_group(own_key) != group) {
2167 LOG_INVALID_PARAMETERS();
2168 return NULL;
2169 }
2170
2171 ret = _crypto_ecdh_init(group);
2172 if (ret) {
2173 /* Already init'ed to the right group. Enough to substitute the
2174 * key. */
2175 ecc_key_deinit(ret->ec->key);
2176 ret->ec->key = own_key->eckey;
2177 ret->ec->own_key = false;
2178 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2179 if (!ret->ec->key->rng) {
2180 int err = wc_ecc_set_rng(ret->ec->key, ret->rng);
2181
2182 if (err != 0)
2183 LOG_WOLF_ERROR_FUNC(wc_ecc_set_rng, err);
2184 }
2185 #endif /* ECC_TIMING_RESISTANT && !CONFIG_FIPS */
2186 }
2187
2188 return ret;
2189 }
2190
2191
crypto_ecdh_deinit(struct crypto_ecdh * ecdh)2192 void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
2193 {
2194 if (ecdh) {
2195 #if defined(ECC_TIMING_RESISTANT) && !defined(WOLFSSL_OLD_FIPS)
2196 /* Disassociate the rng */
2197 if (ecdh->ec && ecdh->ec->key &&
2198 ecdh->ec->key->rng == ecdh->rng)
2199 (void) wc_ecc_set_rng(ecdh->ec->key, NULL);
2200 #endif /* ECC_TIMING_RESISTANT && !WOLFSSL_OLD_FIPS */
2201 crypto_ec_deinit(ecdh->ec);
2202 wc_rng_deinit(ecdh->rng);
2203 os_free(ecdh);
2204 }
2205 }
2206
2207
crypto_ecdh_get_pubkey(struct crypto_ecdh * ecdh,int inc_y)2208 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
2209 {
2210 struct wpabuf *buf = NULL;
2211 int ret;
2212 int len = ecdh->ec->key->dp->size;
2213
2214 buf = wpabuf_alloc(inc_y ? 2 * len : len);
2215 if (!buf)
2216 goto fail;
2217
2218 ret = crypto_bignum_to_bin((struct crypto_bignum *)
2219 ecdh->ec->key->pubkey.x, wpabuf_put(buf, len),
2220 len, len);
2221 if (ret < 0)
2222 goto fail;
2223 if (inc_y) {
2224 ret = crypto_bignum_to_bin((struct crypto_bignum *)
2225 ecdh->ec->key->pubkey.y,
2226 wpabuf_put(buf, len), len, len);
2227 if (ret < 0)
2228 goto fail;
2229 }
2230
2231 done:
2232 return buf;
2233 fail:
2234 wpabuf_free(buf);
2235 buf = NULL;
2236 goto done;
2237 }
2238
2239
crypto_ecdh_set_peerkey(struct crypto_ecdh * ecdh,int inc_y,const u8 * key,size_t len)2240 struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
2241 const u8 *key, size_t len)
2242 {
2243 int ret;
2244 struct wpabuf *pubkey = NULL;
2245 struct wpabuf *secret = NULL;
2246 word32 key_len = ecdh->ec->key->dp->size;
2247 ecc_point *point = NULL;
2248 size_t need_key_len = inc_y ? 2 * key_len : key_len;
2249
2250 if (len < need_key_len) {
2251 LOG_WOLF_ERROR("key len too small");
2252 goto fail;
2253 }
2254 pubkey = wpabuf_alloc(1 + 2 * key_len);
2255 if (!pubkey) {
2256 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2257 goto fail;
2258 }
2259 wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN);
2260 wpabuf_put_data(pubkey, key, need_key_len);
2261
2262 point = wc_ecc_new_point();
2263 if (!point) {
2264 LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
2265 goto fail;
2266 }
2267
2268 ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len,
2269 ecdh->ec->key->idx, point);
2270 if (ret != MP_OKAY) {
2271 LOG_WOLF_ERROR_FUNC(wc_ecc_import_point_der, ret);
2272 goto fail;
2273 }
2274
2275 secret = wpabuf_alloc(key_len);
2276 if (!secret) {
2277 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2278 goto fail;
2279 }
2280
2281 ret = wc_ecc_shared_secret_ex(ecdh->ec->key, point,
2282 wpabuf_put(secret, key_len), &key_len);
2283 if (ret != MP_OKAY) {
2284 LOG_WOLF_ERROR_FUNC(wc_ecc_shared_secret_ex, ret);
2285 goto fail;
2286 }
2287
2288 done:
2289 wc_ecc_del_point(point);
2290 wpabuf_free(pubkey);
2291 return secret;
2292 fail:
2293 wpabuf_free(secret);
2294 secret = NULL;
2295 goto done;
2296 }
2297
2298
crypto_ecdh_prime_len(struct crypto_ecdh * ecdh)2299 size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
2300 {
2301 return crypto_ec_prime_len(ecdh->ec);
2302 }
2303
crypto_ec_key_init(void)2304 static struct crypto_ec_key * crypto_ec_key_init(void)
2305 {
2306 struct crypto_ec_key *key;
2307
2308 key = os_zalloc(sizeof(struct crypto_ec_key));
2309 if (key) {
2310 key->eckey = ecc_key_init();
2311 /* Omit key->rng initialization because it seeds itself and thus
2312 * consumes entropy that may never be used. Lazy initialize when
2313 * necessary. */
2314 if (!key->eckey) {
2315 LOG_WOLF_ERROR_FUNC_NULL(ecc_key_init);
2316 crypto_ec_key_deinit(key);
2317 key = NULL;
2318 }
2319 }
2320 return key;
2321 }
2322
2323
crypto_ec_key_deinit(struct crypto_ec_key * key)2324 void crypto_ec_key_deinit(struct crypto_ec_key *key)
2325 {
2326 if (key) {
2327 ecc_key_deinit(key->eckey);
2328 wc_rng_deinit(key->rng);
2329 os_free(key);
2330 }
2331 }
2332
2333
crypto_ec_key_init_rng(struct crypto_ec_key * key)2334 static WC_RNG * crypto_ec_key_init_rng(struct crypto_ec_key *key)
2335 {
2336 if (!key->rng) {
2337 /* Lazy init key->rng */
2338 key->rng = wc_rng_init();
2339 if (!key->rng)
2340 LOG_WOLF_ERROR_FUNC_NULL(wc_rng_init);
2341 }
2342 return key->rng;
2343 }
2344
2345
crypto_ec_key_parse_priv(const u8 * der,size_t der_len)2346 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
2347 {
2348 struct crypto_ec_key *ret;
2349 word32 idx = 0;
2350 int err;
2351
2352 ret = crypto_ec_key_init();
2353 if (!ret) {
2354 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2355 goto fail;
2356 }
2357
2358 err = wc_EccPrivateKeyDecode(der, &idx, ret->eckey, (word32) der_len);
2359 if (err != 0) {
2360 LOG_WOLF_ERROR_FUNC(wc_EccPrivateKeyDecode, err);
2361 goto fail;
2362 }
2363
2364 return ret;
2365 fail:
2366 if (ret)
2367 crypto_ec_key_deinit(ret);
2368 return NULL;
2369 }
2370
2371
crypto_ec_key_group(struct crypto_ec_key * key)2372 int crypto_ec_key_group(struct crypto_ec_key *key)
2373 {
2374
2375 if (!key || !key->eckey || !key->eckey->dp) {
2376 LOG_INVALID_PARAMETERS();
2377 return -1;
2378 }
2379
2380 switch (key->eckey->dp->id) {
2381 case ECC_SECP256R1:
2382 return 19;
2383 case ECC_SECP384R1:
2384 return 20;
2385 case ECC_SECP521R1:
2386 return 21;
2387 case ECC_SECP192R1:
2388 return 25;
2389 case ECC_SECP224R1:
2390 return 26;
2391 #ifdef HAVE_ECC_BRAINPOOL
2392 case ECC_BRAINPOOLP224R1:
2393 return 27;
2394 case ECC_BRAINPOOLP256R1:
2395 return 28;
2396 case ECC_BRAINPOOLP384R1:
2397 return 29;
2398 case ECC_BRAINPOOLP512R1:
2399 return 30;
2400 #endif /* HAVE_ECC_BRAINPOOL */
2401 }
2402
2403 LOG_WOLF_ERROR_VA("Unsupported curve (id=%d) in EC key",
2404 key->eckey->dp->id);
2405 return -1;
2406 }
2407
2408
crypto_ec_key_gen_public_key(struct crypto_ec_key * key)2409 static int crypto_ec_key_gen_public_key(struct crypto_ec_key *key)
2410 {
2411 int err;
2412
2413 #ifdef WOLFSSL_OLD_FIPS
2414 err = wc_ecc_make_pub(key->eckey, NULL);
2415 #else /* WOLFSSL_OLD_FIPS */
2416 /* Have wolfSSL generate the public key to make it available for output
2417 */
2418 if (!crypto_ec_key_init_rng(key)) {
2419 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2420 return -1;
2421 }
2422
2423 err = wc_ecc_make_pub_ex(key->eckey, NULL, key->rng);
2424 #endif /* WOLFSSL_OLD_FIPS */
2425
2426 if (err != MP_OKAY) {
2427 LOG_WOLF_ERROR_FUNC(wc_ecc_make_pub_ex, err);
2428 return -1;
2429 }
2430
2431 return 0;
2432 }
2433
2434
crypto_ec_key_get_subject_public_key(struct crypto_ec_key * key)2435 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
2436 {
2437 int der_len;
2438 struct wpabuf *ret = NULL;
2439 int err;
2440
2441 if (!key || !key->eckey) {
2442 LOG_INVALID_PARAMETERS();
2443 goto fail;
2444 }
2445
2446 #ifdef WOLFSSL_OLD_FIPS
2447 if (key->eckey->type == ECC_PRIVATEKEY_ONLY &&
2448 crypto_ec_key_gen_public_key(key) != 0) {
2449 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2450 goto fail;
2451 }
2452 #endif /* WOLFSSL_OLD_FIPS */
2453
2454 der_len = err = wc_EccPublicKeyToDer_ex(key->eckey, NULL, 0, 1, 1);
2455 if (err == ECC_PRIVATEONLY_E) {
2456 if (crypto_ec_key_gen_public_key(key) != 0) {
2457 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2458 goto fail;
2459 }
2460 der_len = err = wc_EccPublicKeyToDer_ex(key->eckey, NULL, 0, 1,
2461 1);
2462 }
2463 if (err <= 0) {
2464 LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyDerSize, err);
2465 goto fail;
2466 }
2467
2468 ret = wpabuf_alloc(der_len);
2469 if (!ret) {
2470 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2471 goto fail;
2472 }
2473
2474 err = wc_EccPublicKeyToDer_ex(key->eckey, wpabuf_mhead(ret), der_len, 1,
2475 1);
2476 if (err == ECC_PRIVATEONLY_E) {
2477 if (crypto_ec_key_gen_public_key(key) != 0) {
2478 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2479 goto fail;
2480 }
2481 err = wc_EccPublicKeyToDer_ex(key->eckey, wpabuf_mhead(ret),
2482 der_len, 1, 1);
2483 }
2484 if (err <= 0) {
2485 LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyToDer, err);
2486 goto fail;
2487 }
2488 der_len = err;
2489 wpabuf_put(ret, der_len);
2490
2491 return ret;
2492
2493 fail:
2494 wpabuf_free(ret);
2495 return NULL;
2496 }
2497
2498
crypto_ec_key_parse_pub(const u8 * der,size_t der_len)2499 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
2500 {
2501 word32 idx = 0;
2502 struct crypto_ec_key *ret = NULL;
2503 int err;
2504
2505 ret = crypto_ec_key_init();
2506 if (!ret) {
2507 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2508 goto fail;
2509 }
2510
2511 err = wc_EccPublicKeyDecode(der, &idx, ret->eckey, (word32) der_len);
2512 if (err != 0) {
2513 LOG_WOLF_ERROR_FUNC(wc_EccPublicKeyDecode, err);
2514 goto fail;
2515 }
2516
2517 return ret;
2518 fail:
2519 crypto_ec_key_deinit(ret);
2520 return NULL;
2521 }
2522
2523
crypto_ec_key_sign(struct crypto_ec_key * key,const u8 * data,size_t len)2524 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
2525 size_t len)
2526 {
2527 int der_len;
2528 int err;
2529 word32 w32_der_len;
2530 struct wpabuf *ret = NULL;
2531
2532 if (!key || !key->eckey || !data || len == 0) {
2533 LOG_INVALID_PARAMETERS();
2534 goto fail;
2535 }
2536
2537 if (!crypto_ec_key_init_rng(key)) {
2538 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2539 goto fail;
2540 }
2541
2542 der_len = wc_ecc_sig_size(key->eckey);
2543 if (der_len <= 0) {
2544 LOG_WOLF_ERROR_FUNC(wc_ecc_sig_size, der_len);
2545 goto fail;
2546 }
2547
2548 ret = wpabuf_alloc(der_len);
2549 if (!ret) {
2550 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2551 goto fail;
2552 }
2553
2554 w32_der_len = (word32) der_len;
2555 err = wc_ecc_sign_hash(data, len, wpabuf_mhead(ret), &w32_der_len,
2556 key->rng, key->eckey);
2557 if (err != 0) {
2558 LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash, err);
2559 goto fail;
2560 }
2561 wpabuf_put(ret, w32_der_len);
2562
2563 return ret;
2564 fail:
2565 wpabuf_free(ret);
2566 return NULL;
2567 }
2568
2569
crypto_ec_key_verify_signature(struct crypto_ec_key * key,const u8 * data,size_t len,const u8 * sig,size_t sig_len)2570 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
2571 size_t len, const u8 *sig, size_t sig_len)
2572 {
2573 int res = 0;
2574
2575 if (!key || !key->eckey || !data || len == 0 || !sig || sig_len == 0) {
2576 LOG_INVALID_PARAMETERS();
2577 return -1;
2578 }
2579
2580 if (wc_ecc_verify_hash(sig, sig_len, data, len, &res, key->eckey) != 0)
2581 {
2582 LOG_WOLF_ERROR("wc_ecc_verify_hash failed");
2583 return -1;
2584 }
2585
2586 if (res != 1)
2587 LOG_WOLF_ERROR("crypto_ec_key_verify_signature failed");
2588
2589 return res;
2590 }
2591
2592 #endif /* CONFIG_ECC */
2593
2594 #ifdef CONFIG_DPP
2595
crypto_ec_key_get_ecprivate_key(struct crypto_ec_key * key,bool include_pub)2596 struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
2597 bool include_pub)
2598 {
2599 int len;
2600 int err;
2601 struct wpabuf *ret = NULL;
2602
2603 if (!key || !key->eckey) {
2604 LOG_INVALID_PARAMETERS();
2605 return NULL;
2606 }
2607
2608 #ifdef WOLFSSL_OLD_FIPS
2609 if (key->eckey->type != ECC_PRIVATEKEY &&
2610 key->eckey->type != ECC_PRIVATEKEY_ONLY) {
2611 LOG_INVALID_PARAMETERS();
2612 return NULL;
2613 }
2614 #endif /* WOLFSSL_OLD_FIPS */
2615
2616 len = err = wc_EccKeyDerSize(key->eckey, include_pub);
2617 if (err == ECC_PRIVATEONLY_E && include_pub) {
2618 if (crypto_ec_key_gen_public_key(key) != 0) {
2619 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2620 return NULL;
2621 }
2622 len = err = wc_EccKeyDerSize(key->eckey, include_pub);
2623 }
2624 if (err <= 0) {
2625 /* Exception for BAD_FUNC_ARG because higher levels blindly call
2626 * this function to determine if this is a private key or not.
2627 * BAD_FUNC_ARG most probably means that key->eckey is a public
2628 * key not private. */
2629 if (err != BAD_FUNC_ARG)
2630 LOG_WOLF_ERROR_FUNC(wc_EccKeyDerSize, err);
2631 return NULL;
2632 }
2633
2634 ret = wpabuf_alloc(len);
2635 if (!ret) {
2636 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2637 return NULL;
2638 }
2639
2640 if (include_pub)
2641 err = wc_EccKeyToDer(key->eckey, wpabuf_put(ret, len), len);
2642 else
2643 err = wc_EccPrivateKeyToDer(key->eckey, wpabuf_put(ret, len),
2644 len);
2645
2646 if (err != len) {
2647 LOG_WOLF_ERROR_VA("%s failed with err: %d", include_pub ?
2648 "wc_EccKeyToDer" : "wc_EccPrivateKeyToDer",
2649 err);
2650 wpabuf_free(ret);
2651 ret = NULL;
2652 }
2653
2654 return ret;
2655 }
2656
2657
crypto_ec_key_get_pubkey_point(struct crypto_ec_key * key,int prefix)2658 struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
2659 int prefix)
2660 {
2661 int err;
2662 word32 len = 0;
2663 struct wpabuf *ret = NULL;
2664
2665 if (!key || !key->eckey) {
2666 LOG_INVALID_PARAMETERS();
2667 return NULL;
2668 }
2669
2670 err = wc_ecc_export_x963(key->eckey, NULL, &len);
2671 if (err != LENGTH_ONLY_E) {
2672 LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2673 goto fail;
2674 }
2675
2676 ret = wpabuf_alloc(len);
2677 if (!ret) {
2678 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
2679 goto fail;
2680 }
2681
2682 err = wc_ecc_export_x963(key->eckey, wpabuf_mhead(ret), &len);
2683 if (err == ECC_PRIVATEONLY_E) {
2684 if (crypto_ec_key_gen_public_key(key) != 0) {
2685 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2686 goto fail;
2687 }
2688 err = wc_ecc_export_x963(key->eckey, wpabuf_mhead(ret), &len);
2689 }
2690 if (err != MP_OKAY) {
2691 LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2692 goto fail;
2693 }
2694
2695 if (!prefix)
2696 os_memmove(wpabuf_mhead(ret), wpabuf_mhead_u8(ret) + 1,
2697 (size_t)--len);
2698 wpabuf_put(ret, len);
2699
2700 return ret;
2701
2702 fail:
2703 wpabuf_free(ret);
2704 return NULL;
2705 }
2706
2707
crypto_ec_key_set_pub(int group,const u8 * x,const u8 * y,size_t len)2708 struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
2709 const u8 *y, size_t len)
2710 {
2711 struct crypto_ec_key *ret = NULL;
2712 int curve_id = crypto_ec_group_2_id(group);
2713 int err;
2714
2715 if (!x || !y || len == 0 || curve_id == ECC_CURVE_INVALID ||
2716 wc_ecc_get_curve_size_from_id(curve_id) != (int) len) {
2717 LOG_INVALID_PARAMETERS();
2718 return NULL;
2719 }
2720
2721 ret = crypto_ec_key_init();
2722 if (!ret) {
2723 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2724 return NULL;
2725 }
2726
2727 /* Cast necessary for FIPS API */
2728 err = wc_ecc_import_unsigned(ret->eckey, (u8 *) x, (u8 *) y, NULL,
2729 curve_id);
2730 if (err != MP_OKAY) {
2731 LOG_WOLF_ERROR_FUNC(wc_ecc_import_unsigned, err);
2732 crypto_ec_key_deinit(ret);
2733 return NULL;
2734 }
2735
2736 return ret;
2737 }
2738
2739
crypto_ec_key_cmp(struct crypto_ec_key * key1,struct crypto_ec_key * key2)2740 int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
2741 {
2742 int ret;
2743 struct wpabuf *key1_buf = crypto_ec_key_get_subject_public_key(key1);
2744 struct wpabuf *key2_buf = crypto_ec_key_get_subject_public_key(key2);
2745
2746 if ((key1 && !key1_buf) || (key2 && !key2_buf)) {
2747 LOG_WOLF_ERROR("crypto_ec_key_get_subject_public_key failed");
2748 return -1;
2749 }
2750
2751 ret = wpabuf_cmp(key1_buf, key2_buf);
2752 if (ret != 0)
2753 ret = -1; /* Default to -1 for different keys */
2754
2755 wpabuf_clear_free(key1_buf);
2756 wpabuf_clear_free(key2_buf);
2757 return ret;
2758 }
2759
2760
2761 /* wolfSSL doesn't have a pretty print function for keys so just print out the
2762 * PEM of the private key. */
crypto_ec_key_debug_print(const struct crypto_ec_key * key,const char * title)2763 void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
2764 const char *title)
2765 {
2766 struct wpabuf * key_buf;
2767 struct wpabuf * out = NULL;
2768 int err;
2769 int pem_len;
2770
2771 if (!key || !key->eckey) {
2772 LOG_INVALID_PARAMETERS();
2773 return;
2774 }
2775
2776 if (key->eckey->type == ECC_PUBLICKEY)
2777 key_buf = crypto_ec_key_get_subject_public_key(
2778 (struct crypto_ec_key *) key);
2779 else
2780 key_buf = crypto_ec_key_get_ecprivate_key(
2781 (struct crypto_ec_key *) key, 1);
2782
2783 if (!key_buf) {
2784 LOG_WOLF_ERROR_VA("%s has returned NULL",
2785 key->eckey->type == ECC_PUBLICKEY ?
2786 "crypto_ec_key_get_subject_public_key" :
2787 "crypto_ec_key_get_ecprivate_key");
2788 goto fail;
2789 }
2790
2791 if (!title)
2792 title = "";
2793
2794 err = wc_DerToPem(wpabuf_head(key_buf), wpabuf_len(key_buf), NULL, 0,
2795 ECC_TYPE);
2796 if (err <= 0) {
2797 LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
2798 goto fail;
2799 }
2800 pem_len = err;
2801
2802 out = wpabuf_alloc(pem_len + 1);
2803 if (!out) {
2804 LOG_WOLF_ERROR_FUNC_NULL(wc_DerToPem);
2805 goto fail;
2806 }
2807
2808 err = wc_DerToPem(wpabuf_head(key_buf), wpabuf_len(key_buf),
2809 wpabuf_mhead(out), pem_len, ECC_TYPE);
2810 if (err <= 0) {
2811 LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
2812 goto fail;
2813 }
2814
2815 wpabuf_mhead_u8(out)[err] = '\0';
2816 wpabuf_put(out, err + 1);
2817 wpa_printf(MSG_DEBUG, "%s:\n%s", title,
2818 (const char *) wpabuf_head(out));
2819
2820 fail:
2821 wpabuf_clear_free(key_buf);
2822 wpabuf_clear_free(out);
2823 }
2824
2825
crypto_ec_point_debug_print(const struct crypto_ec * e,const struct crypto_ec_point * p,const char * title)2826 void crypto_ec_point_debug_print(const struct crypto_ec *e,
2827 const struct crypto_ec_point *p,
2828 const char *title)
2829 {
2830 u8 x[ECC_MAXSIZE];
2831 u8 y[ECC_MAXSIZE];
2832 int coord_size;
2833 int err;
2834
2835 if (!p || !e) {
2836 LOG_INVALID_PARAMETERS();
2837 return;
2838 }
2839
2840 coord_size = e->key->dp->size;
2841
2842 if (!title)
2843 title = "";
2844
2845 err = crypto_ec_point_to_bin((struct crypto_ec *)e, p, x, y);
2846 if (err != 0) {
2847 LOG_WOLF_ERROR_FUNC(crypto_ec_point_to_bin, err);
2848 return;
2849 }
2850
2851 wpa_hexdump(MSG_DEBUG, title, x, coord_size);
2852 wpa_hexdump(MSG_DEBUG, title, y, coord_size);
2853 }
2854
2855
crypto_ec_key_gen(int group)2856 struct crypto_ec_key * crypto_ec_key_gen(int group)
2857 {
2858 int curve_id = crypto_ec_group_2_id(group);
2859 int err;
2860 struct crypto_ec_key * ret = NULL;
2861
2862 if (curve_id == ECC_CURVE_INVALID) {
2863 LOG_INVALID_PARAMETERS();
2864 return NULL;
2865 }
2866
2867 ret = crypto_ec_key_init();
2868 if (!ret) {
2869 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
2870 return NULL;
2871 }
2872
2873 if (!crypto_ec_key_init_rng(ret)) {
2874 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
2875 goto fail;
2876 }
2877
2878 err = wc_ecc_make_key_ex(ret->rng, 0, ret->eckey, curve_id);
2879 if (err != MP_OKAY) {
2880 LOG_WOLF_ERROR_FUNC(wc_ecc_make_key_ex, err);
2881 goto fail;
2882 }
2883
2884 return ret;
2885 fail:
2886 crypto_ec_key_deinit(ret);
2887 return NULL;
2888 }
2889
2890
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)2891 int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
2892 const u8 *data, size_t len,
2893 const u8 *r, size_t r_len,
2894 const u8 *s, size_t s_len)
2895 {
2896 int err;
2897 u8 sig[ECC_MAX_SIG_SIZE];
2898 word32 sig_len = ECC_MAX_SIG_SIZE;
2899
2900 if (!key || !key->eckey || !data || !len || !r || !r_len ||
2901 !s || !s_len) {
2902 LOG_INVALID_PARAMETERS();
2903 return -1;
2904 }
2905
2906 err = wc_ecc_rs_raw_to_sig(r, r_len, s, s_len, sig, &sig_len);
2907 if (err != MP_OKAY) {
2908 LOG_WOLF_ERROR_FUNC(wc_ecc_rs_raw_to_sig, err);
2909 return -1;
2910 }
2911
2912 return crypto_ec_key_verify_signature(key, data, len, sig, sig_len);
2913 }
2914
2915
crypto_ec_key_get_public_key(struct crypto_ec_key * key)2916 struct crypto_ec_point * crypto_ec_key_get_public_key(struct crypto_ec_key *key)
2917 {
2918 ecc_point *point = NULL;
2919 int err;
2920 u8 *der = NULL;
2921 word32 der_len = 0;
2922
2923 if (!key || !key->eckey || !key->eckey->dp) {
2924 LOG_INVALID_PARAMETERS();
2925 goto fail;
2926 }
2927
2928 err = wc_ecc_export_x963(key->eckey, NULL, &der_len);
2929 if (err != LENGTH_ONLY_E) {
2930 LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2931 goto fail;
2932 }
2933
2934 der = os_malloc(der_len);
2935 if (!der) {
2936 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
2937 goto fail;
2938 }
2939
2940 err = wc_ecc_export_x963(key->eckey, der, &der_len);
2941 if (err == ECC_PRIVATEONLY_E) {
2942 if (crypto_ec_key_gen_public_key(key) != 0) {
2943 LOG_WOLF_ERROR_FUNC(crypto_ec_key_gen_public_key, -1);
2944 goto fail;
2945 }
2946 err = wc_ecc_export_x963(key->eckey, der, &der_len);
2947 }
2948 if (err != MP_OKAY) {
2949 LOG_WOLF_ERROR_FUNC(wc_ecc_export_x963, err);
2950 goto fail;
2951 }
2952
2953 point = wc_ecc_new_point();
2954 if (!point) {
2955 LOG_WOLF_ERROR_FUNC_NULL(wc_ecc_new_point);
2956 goto fail;
2957 }
2958
2959 err = wc_ecc_import_point_der(der, der_len, key->eckey->idx, point);
2960 if (err != MP_OKAY) {
2961 LOG_WOLF_ERROR_FUNC(wc_ecc_import_point_der, err);
2962 goto fail;
2963 }
2964
2965 os_free(der);
2966 return (struct crypto_ec_point *) point;
2967
2968 fail:
2969 os_free(der);
2970 if (point)
2971 wc_ecc_del_point(point);
2972 return NULL;
2973 }
2974
2975
crypto_ec_key_get_private_key(struct crypto_ec_key * key)2976 struct crypto_bignum * crypto_ec_key_get_private_key(struct crypto_ec_key *key)
2977 {
2978 u8 priv[ECC_MAXSIZE];
2979 word32 priv_len = ECC_MAXSIZE;
2980 #ifdef WOLFSSL_OLD_FIPS
2981 /* Needed to be compliant with the old API */
2982 u8 qx[ECC_MAXSIZE];
2983 word32 qx_len = ECC_MAXSIZE;
2984 u8 qy[ECC_MAXSIZE];
2985 word32 qy_len = ECC_MAXSIZE;
2986 #endif /* WOLFSSL_OLD_FIPS */
2987 struct crypto_bignum *ret = NULL;
2988 int err;
2989
2990 if (!key || !key->eckey) {
2991 LOG_INVALID_PARAMETERS();
2992 return NULL;
2993 }
2994
2995 #ifndef WOLFSSL_OLD_FIPS
2996 err = wc_ecc_export_private_raw(key->eckey, NULL, NULL, NULL, NULL,
2997 priv, &priv_len);
2998 #else /* WOLFSSL_OLD_FIPS */
2999 err = wc_ecc_export_private_raw(key->eckey, qx, &qx_len, qy, &qy_len,
3000 priv, &priv_len);
3001 #endif /* WOLFSSL_OLD_FIPS */
3002 if (err != MP_OKAY) {
3003 LOG_WOLF_ERROR_FUNC(wc_ecc_export_private_raw, err);
3004 return NULL;
3005 }
3006
3007 ret = crypto_bignum_init_set(priv, priv_len);
3008 forced_memzero(priv, priv_len);
3009 return ret;
3010 }
3011
3012
crypto_ec_key_sign_r_s(struct crypto_ec_key * key,const u8 * data,size_t len)3013 struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
3014 const u8 *data, size_t len)
3015 {
3016 int err;
3017 u8 success = 0;
3018 mp_int r;
3019 mp_int s;
3020 u8 rs_init = 0;
3021 int sz;
3022 struct wpabuf * ret = NULL;
3023
3024 if (!key || !key->eckey || !key->eckey->dp || !data || !len) {
3025 LOG_INVALID_PARAMETERS();
3026 return NULL;
3027 }
3028
3029 sz = key->eckey->dp->size;
3030
3031 if (!crypto_ec_key_init_rng(key)) {
3032 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
3033 goto fail;
3034 }
3035
3036 err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL);
3037 if (err != MP_OKAY) {
3038 LOG_WOLF_ERROR_FUNC(mp_init_multi, err);
3039 goto fail;
3040 }
3041 rs_init = 1;
3042
3043 err = wc_ecc_sign_hash_ex(data, len, key->rng, key->eckey, &r, &s);
3044 if (err != MP_OKAY) {
3045 LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash_ex, err);
3046 goto fail;
3047 }
3048
3049 if (mp_unsigned_bin_size(&r) > sz || mp_unsigned_bin_size(&s) > sz) {
3050 LOG_WOLF_ERROR_VA("Unexpected size of r or s (%d %d %d)", sz,
3051 mp_unsigned_bin_size(&r),
3052 mp_unsigned_bin_size(&s));
3053 goto fail;
3054 }
3055
3056 ret = wpabuf_alloc(2 * sz);
3057 if (!ret) {
3058 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3059 goto fail;
3060 }
3061
3062 err = mp_to_unsigned_bin_len(&r, wpabuf_put(ret, sz), sz);
3063 if (err == MP_OKAY)
3064 err = mp_to_unsigned_bin_len(&s, wpabuf_put(ret, sz), sz);
3065 if (err != MP_OKAY) {
3066 LOG_WOLF_ERROR_FUNC(wc_ecc_sign_hash_ex, err);
3067 goto fail;
3068 }
3069
3070 success = 1;
3071 fail:
3072 if (rs_init) {
3073 mp_free(&r);
3074 mp_free(&s);
3075 }
3076 if (!success) {
3077 wpabuf_free(ret);
3078 ret = NULL;
3079 }
3080
3081 return ret;
3082 }
3083
3084
3085 struct crypto_ec_key *
crypto_ec_key_set_pub_point(struct crypto_ec * e,const struct crypto_ec_point * pub)3086 crypto_ec_key_set_pub_point(struct crypto_ec *e,
3087 const struct crypto_ec_point *pub)
3088 {
3089 struct crypto_ec_key *ret = NULL;
3090 int err;
3091 byte *buf = NULL;
3092 word32 buf_len = 0;
3093
3094 if (!e || !pub) {
3095 LOG_INVALID_PARAMETERS();
3096 return NULL;
3097 }
3098
3099 /* Export to DER to not mess with wolfSSL internals */
3100 err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(e->curve_id),
3101 (ecc_point *) pub, NULL, &buf_len);
3102 if (err != LENGTH_ONLY_E || !buf_len) {
3103 LOG_WOLF_ERROR_FUNC(wc_ecc_export_point_der, err);
3104 goto fail;
3105 }
3106
3107 buf = os_malloc(buf_len);
3108 if (!buf) {
3109 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3110 goto fail;
3111 }
3112
3113 err = wc_ecc_export_point_der(wc_ecc_get_curve_idx(e->curve_id),
3114 (ecc_point *) pub, buf, &buf_len);
3115 if (err != MP_OKAY) {
3116 LOG_WOLF_ERROR_FUNC(wc_ecc_export_point_der, err);
3117 goto fail;
3118 }
3119
3120 ret = crypto_ec_key_init();
3121 if (!ret) {
3122 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init);
3123 goto fail;
3124 }
3125
3126 err = wc_ecc_import_x963_ex(buf, buf_len, ret->eckey, e->curve_id);
3127 if (err != MP_OKAY) {
3128 LOG_WOLF_ERROR_FUNC(wc_ecc_import_x963_ex, err);
3129 goto fail;
3130 }
3131
3132 os_free(buf);
3133 return ret;
3134
3135 fail:
3136 os_free(buf);
3137 crypto_ec_key_deinit(ret);
3138 return NULL;
3139 }
3140
3141
crypto_pkcs7_get_certificates(const struct wpabuf * pkcs7)3142 struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
3143 {
3144 PKCS7 *p7 = NULL;
3145 struct wpabuf *ret = NULL;
3146 int err = 0;
3147 int total_sz = 0;
3148 int i;
3149
3150 if (!pkcs7) {
3151 LOG_INVALID_PARAMETERS();
3152 return NULL;
3153 }
3154
3155 p7 = wc_PKCS7_New(NULL, INVALID_DEVID);
3156 if (!p7) {
3157 LOG_WOLF_ERROR_FUNC_NULL(wc_PKCS7_New);
3158 return NULL;
3159 }
3160
3161 err = wc_PKCS7_VerifySignedData(p7, (byte *) wpabuf_head(pkcs7),
3162 wpabuf_len(pkcs7));
3163 if (err != 0) {
3164 LOG_WOLF_ERROR_FUNC(wc_PKCS7_VerifySignedData, err);
3165 wc_PKCS7_Free(p7);
3166 goto fail;
3167 }
3168
3169 /* Need to access p7 members directly */
3170 for (i = 0; i < MAX_PKCS7_CERTS; i++) {
3171 if (p7->certSz[i] == 0)
3172 continue;
3173 err = wc_DerToPem(p7->cert[i], p7->certSz[i], NULL, 0,
3174 CERT_TYPE);
3175 if (err > 0) {
3176 total_sz += err;
3177 } else {
3178 LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
3179 goto fail;
3180 }
3181 }
3182
3183 if (total_sz == 0) {
3184 LOG_WOLF_ERROR("No certificates found in PKCS7 input");
3185 goto fail;
3186 }
3187
3188 ret = wpabuf_alloc(total_sz);
3189 if (!ret) {
3190 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc);
3191 goto fail;
3192 }
3193
3194 /* Need to access p7 members directly */
3195 for (i = 0; i < MAX_PKCS7_CERTS; i++) {
3196 if (p7->certSz[i] == 0)
3197 continue;
3198 /* Not using wpabuf_put() here so that wpabuf_overflow() isn't
3199 * called in case of a size mismatch. wc_DerToPem() checks if
3200 * the output is large enough internally. */
3201 err = wc_DerToPem(p7->cert[i], p7->certSz[i],
3202 wpabuf_mhead_u8(ret) + wpabuf_len(ret),
3203 wpabuf_tailroom(ret),
3204 CERT_TYPE);
3205 if (err > 0) {
3206 wpabuf_put(ret, err);
3207 } else {
3208 LOG_WOLF_ERROR_FUNC(wc_DerToPem, err);
3209 wpabuf_free(ret);
3210 ret = NULL;
3211 goto fail;
3212 }
3213 }
3214
3215 fail:
3216 if (p7)
3217 wc_PKCS7_Free(p7);
3218 return ret;
3219 }
3220
3221
3222 /* BEGIN Certificate Signing Request (CSR) APIs */
3223
3224 enum cert_type {
3225 cert_type_none = 0,
3226 cert_type_decoded_cert,
3227 cert_type_cert,
3228 };
3229
3230 struct crypto_csr {
3231 union {
3232 /* For parsed csr should be read-only for higher levels */
3233 DecodedCert dc;
3234 Cert c; /* For generating a csr */
3235 } req;
3236 enum cert_type type;
3237 struct crypto_ec_key *pubkey;
3238 };
3239
3240
3241 /* 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)3242 static void crypto_csr_init_type(struct crypto_csr *csr, enum cert_type type,
3243 const byte *source, word32 in_sz)
3244 {
3245 int err;
3246
3247 if (csr->type == type)
3248 return; /* Already correct type */
3249
3250 switch (csr->type) {
3251 case cert_type_decoded_cert:
3252 wc_FreeDecodedCert(&csr->req.dc);
3253 break;
3254 case cert_type_cert:
3255 #ifdef WOLFSSL_CERT_GEN_CACHE
3256 wc_SetCert_Free(&csr->req.c);
3257 #endif /* WOLFSSL_CERT_GEN_CACHE */
3258 break;
3259 case cert_type_none:
3260 break;
3261 }
3262
3263 switch (type) {
3264 case cert_type_decoded_cert:
3265 wc_InitDecodedCert(&csr->req.dc, source, in_sz, NULL);
3266 break;
3267 case cert_type_cert:
3268 err = wc_InitCert(&csr->req.c);
3269 if (err != 0)
3270 LOG_WOLF_ERROR_FUNC(wc_InitCert, err);
3271 break;
3272 case cert_type_none:
3273 break;
3274 }
3275
3276 csr->type = type;
3277 }
3278
3279
crypto_csr_init(void)3280 struct crypto_csr * crypto_csr_init(void)
3281 {
3282 struct crypto_csr *ret = os_malloc(sizeof(struct crypto_csr));
3283
3284 if (!ret) {
3285 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3286 return NULL;
3287 }
3288
3289 ret->type = cert_type_none;
3290 crypto_csr_init_type(ret, cert_type_cert, NULL, 0);
3291 ret->pubkey = NULL;
3292
3293 return ret;
3294 }
3295
3296
crypto_csr_deinit(struct crypto_csr * csr)3297 void crypto_csr_deinit(struct crypto_csr *csr)
3298 {
3299 if (csr) {
3300 crypto_csr_init_type(csr, cert_type_none, NULL, 0);
3301 crypto_ec_key_deinit(csr->pubkey);
3302 os_free(csr);
3303 }
3304 }
3305
3306
crypto_csr_set_ec_public_key(struct crypto_csr * csr,struct crypto_ec_key * key)3307 int crypto_csr_set_ec_public_key(struct crypto_csr *csr,
3308 struct crypto_ec_key *key)
3309 {
3310 struct wpabuf *der = NULL;
3311
3312 if (!csr || !key || !key->eckey) {
3313 LOG_INVALID_PARAMETERS();
3314 return -1;
3315 }
3316
3317 if (csr->pubkey) {
3318 crypto_ec_key_deinit(csr->pubkey);
3319 csr->pubkey = NULL;
3320 }
3321
3322 /* Create copy of key to mitigate use-after-free errors */
3323 der = crypto_ec_key_get_subject_public_key(key);
3324 if (!der) {
3325 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_get_subject_public_key);
3326 return -1;
3327 }
3328
3329 csr->pubkey = crypto_ec_key_parse_pub(wpabuf_head(der),
3330 wpabuf_len(der));
3331 wpabuf_free(der);
3332 if (!csr->pubkey) {
3333 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_parse_pub);
3334 return -1;
3335 }
3336
3337 return 0;
3338 }
3339
3340
crypto_csr_set_name(struct crypto_csr * csr,enum crypto_csr_name type,const char * name)3341 int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
3342 const char *name)
3343 {
3344 int name_len;
3345 char *dest;
3346
3347 if (!csr || !name) {
3348 LOG_INVALID_PARAMETERS();
3349 return -1;
3350 }
3351
3352 if (csr->type != cert_type_cert) {
3353 LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3354 return -1;
3355 }
3356
3357 name_len = os_strlen(name);
3358 if (name_len >= CTC_NAME_SIZE) {
3359 LOG_WOLF_ERROR("name input too long");
3360 return -1;
3361 }
3362
3363 switch (type) {
3364 case CSR_NAME_CN:
3365 dest = csr->req.c.subject.commonName;
3366 break;
3367 case CSR_NAME_SN:
3368 dest = csr->req.c.subject.sur;
3369 break;
3370 case CSR_NAME_C:
3371 dest = csr->req.c.subject.country;
3372 break;
3373 case CSR_NAME_O:
3374 dest = csr->req.c.subject.org;
3375 break;
3376 case CSR_NAME_OU:
3377 dest = csr->req.c.subject.unit;
3378 break;
3379 default:
3380 LOG_INVALID_PARAMETERS();
3381 return -1;
3382 }
3383
3384 os_memcpy(dest, name, name_len);
3385 dest[name_len] = '\0';
3386
3387 return 0;
3388 }
3389
3390
crypto_csr_set_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,int attr_type,const u8 * value,size_t len)3391 int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
3392 int attr_type, const u8 *value, size_t len)
3393 {
3394 if (!csr || attr_type != ASN1_TAG_UTF8STRING || !value ||
3395 len >= CTC_NAME_SIZE) {
3396 LOG_INVALID_PARAMETERS();
3397 return -1;
3398 }
3399
3400 if (csr->type != cert_type_cert) {
3401 LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3402 return -1;
3403 }
3404
3405 switch (attr) {
3406 case CSR_ATTR_CHALLENGE_PASSWORD:
3407 os_memcpy(csr->req.c.challengePw, value, len);
3408 csr->req.c.challengePw[len] = '\0';
3409 break;
3410 default:
3411 return -1;
3412 }
3413
3414 return 0;
3415 }
3416
3417
crypto_csr_get_attribute(struct crypto_csr * csr,enum crypto_csr_attr attr,size_t * len,int * type)3418 const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
3419 enum crypto_csr_attr attr,
3420 size_t *len, int *type)
3421 {
3422 if (!csr || !len || !type) {
3423 LOG_INVALID_PARAMETERS();
3424 return NULL;;
3425 }
3426
3427 switch (attr) {
3428 case CSR_ATTR_CHALLENGE_PASSWORD:
3429 switch (csr->type) {
3430 case cert_type_decoded_cert:
3431 *type = ASN1_TAG_UTF8STRING;
3432 *len = csr->req.dc.cPwdLen;
3433 return (const u8 *) csr->req.dc.cPwd;
3434 case cert_type_cert:
3435 *type = ASN1_TAG_UTF8STRING;
3436 *len = os_strlen(csr->req.c.challengePw);
3437 return (const u8 *) csr->req.c.challengePw;
3438 case cert_type_none:
3439 return NULL;
3440 }
3441 break;
3442 }
3443 return NULL;
3444 }
3445
3446
crypto_csr_sign(struct crypto_csr * csr,struct crypto_ec_key * key,enum crypto_hash_alg algo)3447 struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
3448 struct crypto_ec_key *key,
3449 enum crypto_hash_alg algo)
3450 {
3451 int err;
3452 int len;
3453 u8 *buf = NULL;
3454 int buf_len;
3455 struct wpabuf *ret = NULL;
3456
3457 if (!csr || !key || !key->eckey) {
3458 LOG_INVALID_PARAMETERS();
3459 return NULL;
3460 }
3461
3462 if (csr->type != cert_type_cert) {
3463 LOG_WOLF_ERROR_VA("csr is incorrect type (%d)", csr->type);
3464 return NULL;
3465 }
3466
3467 if (!crypto_ec_key_init_rng(key)) {
3468 LOG_WOLF_ERROR_FUNC_NULL(crypto_ec_key_init_rng);
3469 return NULL;
3470 }
3471
3472 switch (algo) {
3473 case CRYPTO_HASH_ALG_SHA256:
3474 csr->req.c.sigType = CTC_SHA256wECDSA;
3475 break;
3476 case CRYPTO_HASH_ALG_SHA384:
3477 csr->req.c.sigType = CTC_SHA384wECDSA;
3478 break;
3479 case CRYPTO_HASH_ALG_SHA512:
3480 csr->req.c.sigType = CTC_SHA512wECDSA;
3481 break;
3482 default:
3483 LOG_INVALID_PARAMETERS();
3484 return NULL;
3485 }
3486
3487 /* Pass in large value that is guaranteed to be larger than the
3488 * necessary buffer */
3489 err = wc_MakeCertReq(&csr->req.c, NULL, 100000, NULL,
3490 csr->pubkey->eckey);
3491 if (err <= 0) {
3492 LOG_WOLF_ERROR_FUNC(wc_MakeCertReq, err);
3493 goto fail;
3494 }
3495 len = err;
3496
3497 buf_len = len + MAX_SEQ_SZ * 2 + MAX_ENCODED_SIG_SZ;
3498 buf = os_malloc(buf_len);
3499 if (!buf) {
3500 LOG_WOLF_ERROR_FUNC_NULL(os_malloc);
3501 goto fail;
3502 }
3503
3504 err = wc_MakeCertReq(&csr->req.c, buf, buf_len, NULL,
3505 csr->pubkey->eckey);
3506 if (err <= 0) {
3507 LOG_WOLF_ERROR_FUNC(wc_MakeCertReq, err);
3508 goto fail;
3509 }
3510 len = err;
3511
3512 err = wc_SignCert(len, csr->req.c.sigType, buf, buf_len, NULL,
3513 key->eckey, key->rng);
3514 if (err <= 0) {
3515 LOG_WOLF_ERROR_FUNC(wc_SignCert, err);
3516 goto fail;
3517 }
3518 len = err;
3519
3520 ret = wpabuf_alloc_copy(buf, len);
3521 if (!ret) {
3522 LOG_WOLF_ERROR_FUNC_NULL(wpabuf_alloc_copy);
3523 goto fail;
3524 }
3525
3526 fail:
3527 os_free(buf);
3528 return ret;
3529 }
3530
3531
crypto_csr_verify(const struct wpabuf * req)3532 struct crypto_csr * crypto_csr_verify(const struct wpabuf *req)
3533 {
3534 struct crypto_csr *csr = NULL;
3535 int err;
3536
3537 if (!req) {
3538 LOG_INVALID_PARAMETERS();
3539 return NULL;
3540 }
3541
3542 csr = crypto_csr_init();
3543 if (!csr) {
3544 LOG_WOLF_ERROR_FUNC_NULL(crypto_csr_init);
3545 goto fail;
3546 }
3547
3548 crypto_csr_init_type(csr, cert_type_decoded_cert,
3549 wpabuf_head(req), wpabuf_len(req));
3550 err = wc_ParseCert(&csr->req.dc, CERTREQ_TYPE, VERIFY, NULL);
3551 if (err != 0) {
3552 LOG_WOLF_ERROR_FUNC(wc_ParseCert, err);
3553 goto fail;
3554 }
3555
3556 return csr;
3557 fail:
3558 crypto_csr_deinit(csr);
3559 return NULL;
3560 }
3561
3562 /* END Certificate Signing Request (CSR) APIs */
3563
3564 #endif /* CONFIG_DPP */
3565
3566
crypto_unload(void)3567 void crypto_unload(void)
3568 {
3569 }
3570