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