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