diff --git a/modules/mbedtls/configs/config-tls-generic.h b/modules/mbedtls/configs/config-tls-generic.h index e03a371b3c8..b95d0f1f0f1 100644 --- a/modules/mbedtls/configs/config-tls-generic.h +++ b/modules/mbedtls/configs/config-tls-generic.h @@ -457,6 +457,11 @@ #if defined(CONFIG_MBEDTLS_PSA_CRYPTO_C) #define MBEDTLS_PSA_CRYPTO_C +#define MBEDTLS_USE_PSA_CRYPTO +#endif + +#if defined(CONFIG_MBEDTLS_TLS_VERSION_1_2) && defined(CONFIG_MBEDTLS_PSA_CRYPTO_C) +#define MBEDTLS_SSL_ENCRYPT_THEN_MAC #endif /* User config file */ diff --git a/subsys/bluetooth/mesh/CMakeLists.txt b/subsys/bluetooth/mesh/CMakeLists.txt index e4f6158123e..e4aa8f8933d 100644 --- a/subsys/bluetooth/mesh/CMakeLists.txt +++ b/subsys/bluetooth/mesh/CMakeLists.txt @@ -13,7 +13,6 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH app_keys.c heartbeat.c crypto.c - crypto_tc.c access.c msg.c cfg_srv.c @@ -119,3 +118,9 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_SOL_PDU_RPL_CLI sol_pdu_rpl_cli.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV sol_pdu_rpl_srv.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_SOLICITATION solicitation.c) + +zephyr_library_sources_ifdef(CONFIG_BT_MESH_USES_TINYCRYPT crypto_tc.c) + +zephyr_library_sources_ifdef(CONFIG_BT_MESH_USES_MBEDTLS_PSA crypto_psa.c) + +zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index b66e6ca2210..3f2657a0fdf 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -5,11 +5,6 @@ menuconfig BT_MESH bool "Bluetooth mesh support" - select TINYCRYPT - select TINYCRYPT_AES - select TINYCRYPT_AES_CMAC - select TINYCRYPT_ECC_DH - select BT_HOST_CCM depends on BT_OBSERVER && BT_BROADCASTER help This option enables Bluetooth mesh support. The specific @@ -18,6 +13,48 @@ menuconfig BT_MESH if BT_MESH +choice BT_MESH_CRYPTO_LIB + prompt "Crypto library selection for mesh security" + default BT_MESH_USES_TINYCRYPT + +config BT_MESH_USES_TINYCRYPT + bool "Use TinyCrypt" + select TINYCRYPT + select TINYCRYPT_AES + select TINYCRYPT_AES_CMAC + select TINYCRYPT_ECC_DH + select TINYCRYPT_SHA256 + select TINYCRYPT_SHA256_HMAC + select BT_HOST_CCM + help + Use TinyCrypt library to perform crypto operations. + +config BT_MESH_USES_MBEDTLS_PSA + bool "Use mbed TLS PSA [EXPERIMENTAL]" + select EXPERIMENTAL + select MBEDTLS + select MBEDTLS_ZEPHYR_ENTROPY + select MBEDTLS_PSA_CRYPTO_C + select MBEDTLS_CIPHER + select MBEDTLS_MAC_CMAC_ENABLED + select MBEDTLS_CIPHER_AES_ENABLED + select MBEDTLS_AES_ROM_TABLES + select MBEDTLS_CIPHER_CCM_ENABLED + select MBEDTLS_ECP_C + select MBEDTLS_ECDH_C + select MBEDTLS_ECDSA_C + select MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + select MBEDTLS_ECP_DP_SECP256R1_ENABLED + select MBEDTLS_PK_WRITE_C + help + Use mbed TLS library to perform crypto operations. Support of + mbed TLS and PSA is experimental and only BabbleSim tests were run. + Mbed TLS still does not support ITS (internal trust storage) based + on Zephyr's settings subsystem. + Not possible to use for embedded devices yet. + +endchoice + # Virtual option enabled whenever Generic Provisioning layer is needed config BT_MESH_PROV bool @@ -938,8 +975,6 @@ if BT_MESH_V1d1 config BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM bool "Support HMAC SHA256 for OOB authentication" - select TINYCRYPT_SHA256 - select TINYCRYPT_SHA256_HMAC depends on BT_MESH_PROV default y help diff --git a/subsys/bluetooth/mesh/crypto_psa.c b/subsys/bluetooth/mesh/crypto_psa.c new file mode 100644 index 00000000000..e2bab6d9eaa --- /dev/null +++ b/subsys/bluetooth/mesh/crypto_psa.c @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#include + +#define LOG_LEVEL CONFIG_BT_MESH_CRYPTO_LOG_LEVEL +#include +LOG_MODULE_REGISTER(bt_mesh_crypto_psa); + +#include "mesh.h" +#include "crypto.h" +#include "prov.h" + +static struct { + bool is_ready; + psa_key_id_t priv_key_id; + uint8_t public_key_be[PUB_KEY_SIZE + 1]; +} key; + +int bt_mesh_crypto_init(void) +{ + if (psa_crypto_init() != PSA_SUCCESS) { + return -EIO; + } + + return 0; +} + +int bt_mesh_encrypt(const uint8_t key[16], const uint8_t plaintext[16], uint8_t enc_data[16]) +{ + psa_key_id_t key_id; + uint32_t output_len; + psa_status_t status; + int err = 0; + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 128); + + status = psa_import_key(&key_attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + return -EIO; + } + + status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, + plaintext, 16, + enc_data, 16, + &output_len); + + if (status != PSA_SUCCESS || output_len != 16) { + err = -EIO; + } + + psa_reset_key_attributes(&key_attributes); + + status = psa_destroy_key(key_id); + if (status != PSA_SUCCESS) { + return -EIO; + } + + return err; +} + +int bt_mesh_ccm_encrypt(const uint8_t key[16], uint8_t nonce[13], + const uint8_t *plaintext, size_t len, const uint8_t *aad, + size_t aad_len, uint8_t *enc_data, size_t mic_size) +{ + psa_key_id_t key_id; + uint32_t output_len; + psa_status_t status; + int err = 0; + + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, mic_size); + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&key_attributes, alg); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 128); + + status = psa_import_key(&key_attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + return -EIO; + } + + status = psa_aead_encrypt(key_id, alg, + nonce, 13, + aad, aad_len, + plaintext, len, + enc_data, len + mic_size, + &output_len); + + if (status != PSA_SUCCESS || output_len != len + mic_size) { + err = -EIO; + } + + psa_reset_key_attributes(&key_attributes); + + status = psa_destroy_key(key_id); + if (status != PSA_SUCCESS) { + return -EIO; + } + + return err; +} + +int bt_mesh_ccm_decrypt(const uint8_t key[16], uint8_t nonce[13], + const uint8_t *enc_data, size_t len, const uint8_t *aad, + size_t aad_len, uint8_t *plaintext, size_t mic_size) +{ + psa_key_id_t key_id; + uint32_t output_len; + psa_status_t status; + int err = 0; + + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, mic_size); + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&key_attributes, alg); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 128); + + status = psa_import_key(&key_attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + return -EIO; + } + + status = psa_aead_decrypt(key_id, alg, + nonce, 13, + aad, aad_len, + enc_data, len + mic_size, + plaintext, len, + &output_len); + + if (status != PSA_SUCCESS || output_len != len) { + err = -EIO; + } + + psa_reset_key_attributes(&key_attributes); + + status = psa_destroy_key(key_id); + if (status != PSA_SUCCESS) { + return -EIO; + } + + return err; +} + +int bt_mesh_aes_cmac(const uint8_t key[16], struct bt_mesh_sg *sg, + size_t sg_len, uint8_t mac[16]) +{ + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + psa_algorithm_t alg = PSA_ALG_CMAC; + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; + + psa_status_t status; + int err = 0; + + /* Import a key */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + + status = psa_import_key(&attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + psa_reset_key_attributes(&attributes); + + status = psa_mac_sign_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + for (; sg_len; sg_len--, sg++) { + status = psa_mac_update(&operation, sg->data, sg->len); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + } + + if (PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, alg) > 16) { + err = -ERANGE; + goto end; + } + + size_t mac_len; + + status = psa_mac_sign_finish(&operation, mac, 16, &mac_len); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + if (mac_len != 16) { + err = -ERANGE; + } + +end: + /* Destroy the key */ + psa_destroy_key(key_id); + + return err; +} + +int bt_mesh_sha256_hmac(const uint8_t key[32], struct bt_mesh_sg *sg, size_t sg_len, + uint8_t mac[32]) +{ + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + psa_algorithm_t alg = PSA_ALG_HMAC(PSA_ALG_SHA_256); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; + + psa_status_t status; + int err = 0; + + /* Import a key */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); + psa_set_key_bits(&attributes, 256); + + status = psa_import_key(&attributes, key, 32, &key_id); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + psa_reset_key_attributes(&attributes); + + status = psa_mac_sign_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + for (; sg_len; sg_len--, sg++) { + status = psa_mac_update(&operation, sg->data, sg->len); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + } + + if (PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, 256, alg) > 32) { + err = -ERANGE; + goto end; + } + + size_t mac_len; + + status = psa_mac_sign_finish(&operation, mac, 32, &mac_len); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + if (mac_len != 32) { + err = -ERANGE; + } + +end: + /* Destroy the key */ + psa_destroy_key(key_id); + + return err; +} + +int bt_mesh_pub_key_gen(void) +{ + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + int err = 0; + size_t key_len; + + psa_destroy_key(key.priv_key_id); + key.is_ready = false; + + /* Crypto settings for ECDH using the SHA256 hashing algorithm, + * the secp256r1 curve + */ + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + + /* Generate a key pair */ + status = psa_generate_key(&key_attributes, &key.priv_key_id); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + status = psa_export_public_key(key.priv_key_id, key.public_key_be, + sizeof(key.public_key_be), &key_len); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + if (key_len != PUB_KEY_SIZE + 1) { + err = -ERANGE; + goto end; + } + + key.is_ready = true; + +end: + psa_reset_key_attributes(&key_attributes); + + return err; +} + +const uint8_t *bt_mesh_pub_key_get(void) +{ + return key.is_ready ? key.public_key_be + 1 : NULL; +} + +BUILD_ASSERT(PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( + PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 256) == DH_KEY_SIZE, + "Diffie-Hellman shared secret size should be the same in PSA and BLE Mesh"); + +BUILD_ASSERT(PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256) == PUB_KEY_SIZE + 1, + "Exported PSA public key should be 1 byte larger than BLE Mesh public key"); + +int bt_mesh_dhkey_gen(const uint8_t *pub_key, const uint8_t *priv_key, uint8_t *dhkey) +{ + int err = 0; + psa_key_id_t priv_key_id = PSA_KEY_ID_NULL; + uint8_t public_key_repr[PUB_KEY_SIZE + 1]; + psa_status_t status; + size_t dh_key_len; + + if (priv_key) { + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + /* Import a custom private key */ + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&attributes, PSA_ALG_ECDH); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + status = psa_import_key(&attributes, priv_key, PRIV_KEY_SIZE, &priv_key_id); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + psa_reset_key_attributes(&attributes); + } else { + priv_key_id = key.priv_key_id; + } + + /* For elliptic curve key pairs for Weierstrass curve families (PSA_ECC_FAMILY_SECP_R1) + * the representations of public key is: + * - The byte 0x04; + * - x_P as a ceiling(m/8)-byte string, big-endian; + * - y_P as a ceiling(m/8)-byte string, big-endian. + */ + public_key_repr[0] = 0x04; + memcpy(public_key_repr + 1, pub_key, PUB_KEY_SIZE); + + /* Calculate the secret */ + status = psa_raw_key_agreement(PSA_ALG_ECDH, priv_key_id, public_key_repr, + PUB_KEY_SIZE + 1, dhkey, DH_KEY_SIZE, &dh_key_len); + if (status != PSA_SUCCESS) { + err = -EIO; + goto end; + } + + if (dh_key_len != DH_KEY_SIZE) { + err = -ERANGE; + } + +end: + + if (priv_key) { + psa_destroy_key(priv_key_id); + } + + return err; +} diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index a08c7e6559f..5812dc18956 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -391,6 +391,7 @@ static void test_tx_invalid(void) int err; bt_mesh_test_cfg_set(&tx_cfg, 130); + bt_mesh_crypto_init(); k_sem_init(&observer_sem, 0, 1); err = bt_enable(NULL); @@ -498,6 +499,7 @@ static void test_tx_kr_old_key(void) int err; bt_mesh_test_cfg_set(&tx_cfg, 170); + bt_mesh_crypto_init(); k_sem_init(&observer_sem, 0, 1); err = bt_enable(NULL); @@ -686,6 +688,7 @@ static void test_tx_multiple_netkeys(void) int err; bt_mesh_test_cfg_set(&tx_cfg, MULT_NETKEYS_WAIT_TIME); + bt_mesh_crypto_init(); k_sem_init(&observer_sem, 0, 1); err = bt_enable(NULL); @@ -848,6 +851,7 @@ static void test_rx_secure_beacon_interval(void) int64_t delta; bt_mesh_test_cfg_set(&rx_cfg, BEACON_INTERVAL_WAIT_TIME); + bt_mesh_crypto_init(); k_sem_init(&observer_sem, 0, 1); k_work_init_delayable(&beacon_timer, secure_beacon_send); diff --git a/tests/bsim/bluetooth/mesh/src/test_friendship.c b/tests/bsim/bluetooth/mesh/src/test_friendship.c index e537fd108a0..6652df88a8f 100644 --- a/tests/bsim/bluetooth/mesh/src/test_friendship.c +++ b/tests/bsim/bluetooth/mesh/src/test_friendship.c @@ -541,7 +541,15 @@ static void test_lpn_msg_mesh(void) ASSERT_OK(bt_mesh_lpn_poll()); ASSERT_OK(bt_mesh_test_recv(5, cfg->addr, K_SECONDS(2))); +/* TODO: Test scenario should be redesigned. + * It is extremely fragile to time delays. + * Unstability appears in the low latency test suite. + */ +#if defined CONFIG_BT_MESH_USES_MBEDTLS_PSA + k_sleep(K_SECONDS(2)); +#elif defined CONFIG_BT_MESH_USES_TINYCRYPT k_sleep(K_SECONDS(1)); +#endif /* Send a segmented message to the mesh node. * Should trigger a poll for the ack. diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index 5bd57aeead4..aec2199b3b2 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -13,9 +13,15 @@ #include #include +#if defined CONFIG_BT_MESH_USES_MBEDTLS_PSA +#include +#elif defined CONFIG_BT_MESH_USES_TINYCRYPT #include #include #include +#else +#error "Unknown crypto library has been chosen" +#endif #include @@ -44,7 +50,7 @@ static uint8_t static_key1[] = {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x31}; static uint8_t static_key2[] = {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F}; -static uint8_t private_key_be[64]; +static uint8_t private_key_be[32]; static uint8_t public_key_be[64]; static struct oob_auth_test_vector_s { @@ -326,6 +332,48 @@ static void oob_auth_set(int test_step) prov.input_actions = oob_auth_test_vector[test_step].input_actions; } +#if defined CONFIG_BT_MESH_USES_MBEDTLS_PSA +static void generate_oob_key_pair(void) +{ + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t priv_key_id = PSA_KEY_ID_NULL; + psa_status_t status; + size_t key_len; + uint8_t public_key_repr[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256)]; + + /* Crypto settings for ECDH using the SHA256 hashing algorithm, + * the secp256r1 curve + */ + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + + /* Generate a key pair */ + status = psa_generate_key(&key_attributes, &priv_key_id); + ASSERT_TRUE(status == PSA_SUCCESS); + + status = psa_export_public_key(priv_key_id, public_key_repr, sizeof(public_key_repr), + &key_len); + ASSERT_TRUE(status == PSA_SUCCESS); + + ASSERT_TRUE(key_len == PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256)); + + status = psa_export_key(priv_key_id, private_key_be, sizeof(private_key_be), &key_len); + ASSERT_TRUE(status == PSA_SUCCESS); + + ASSERT_TRUE(key_len == sizeof(private_key_be)); + + memcpy(public_key_be, public_key_repr + 1, 64); +} +#elif defined CONFIG_BT_MESH_USES_TINYCRYPT +static void generate_oob_key_pair(void) +{ + ASSERT_TRUE(uECC_make_key(public_key_be, private_key_be, uECC_secp256r1())); +} +#endif + static void oob_device(bool use_oob_pk) { k_sem_init(&prov_sem, 0, 1); @@ -333,7 +381,7 @@ static void oob_device(bool use_oob_pk) bt_mesh_device_setup(&prov, &comp); if (use_oob_pk) { - ASSERT_TRUE(uECC_make_key(public_key_be, private_key_be, uECC_secp256r1())); + generate_oob_key_pair(); prov.public_key_be = public_key_be; prov.private_key_be = private_key_be; bs_bc_send_msg(*oob_channel_id, public_key_be, 64);