Home | History | Annotate | Line # | Download | only in crypto
      1 /*
      2  * Wrapper functions for libwolfssl
      3  * Copyright (c) 2004-2017, Jouni Malinen <j (at) 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