From 9032f8d791cd3d9d1f14d59390845dc8c760a8c3 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 28 May 2024 07:36:47 +0200 Subject: [PATCH] bt-crypto: add option to use PSA APIs instead of TinyCrypt This commit adds CONFIG_BT_USE_PSA_API to allow the end user to prefer PSA APIs over TinyCrypt for crypto operations in bluetooth. Of course, this is possible only if a PSA provider is available on the system, i.e. CONFIG_PSA_CRYPTO_CLIENT is set. This commit also extends tests/bluetooth/bt_crypto adding a test case for PSA. Signed-off-by: Valerio Setti --- subsys/bluetooth/Kconfig | 7 ++++ subsys/bluetooth/crypto/CMakeLists.txt | 10 +++++ subsys/bluetooth/crypto/Kconfig | 8 ++-- subsys/bluetooth/crypto/bt_crypto.c | 25 ++---------- subsys/bluetooth/crypto/bt_crypto_psa.c | 46 ++++++++++++++++++++++ subsys/bluetooth/crypto/bt_crypto_tc.c | 34 ++++++++++++++++ tests/bluetooth/bt_crypto/testcase.yaml | 16 ++++++++ tests/bluetooth/host/crypto/CMakeLists.txt | 2 +- 8 files changed, 123 insertions(+), 25 deletions(-) create mode 100644 subsys/bluetooth/crypto/bt_crypto_psa.c create mode 100644 subsys/bluetooth/crypto/bt_crypto_tc.c diff --git a/subsys/bluetooth/Kconfig b/subsys/bluetooth/Kconfig index 5e1de57db08..9a9b91f2b18 100644 --- a/subsys/bluetooth/Kconfig +++ b/subsys/bluetooth/Kconfig @@ -192,6 +192,13 @@ rsource "crypto/Kconfig" rsource "lib/Kconfig" rsource "Kconfig.logging" +config BT_USE_PSA_API + bool "Use PSA APIs instead of TinyCrypt for crypto operations" + depends on BT_CRYPTO || BT_HOST_CRYPTO + depends on PSA_CRYPTO_CLIENT + help + Use PSA APIs instead of TinyCrypt for crypto operations + endif # BT_HCI config BT_COMPANY_ID diff --git a/subsys/bluetooth/crypto/CMakeLists.txt b/subsys/bluetooth/crypto/CMakeLists.txt index 9228fc9fd0b..dc0f83b32c2 100644 --- a/subsys/bluetooth/crypto/CMakeLists.txt +++ b/subsys/bluetooth/crypto/CMakeLists.txt @@ -4,6 +4,16 @@ zephyr_library() zephyr_library_sources(bt_crypto.c) +if(CONFIG_BT_USE_PSA_API) + zephyr_library_sources(bt_crypto_psa.c) + zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) + zephyr_library_include_directories_ifdef(CONFIG_BUILD_WITH_TFM + $/api_ns/interface/include + ) +else() + zephyr_library_sources(bt_crypto_tc.c) +endif() + if(CONFIG_BT_CRYPTO_LOG_LEVEL_DBG) message(WARNING "CONFIG_BT_CRYPTO_LOG_LEVEL_DBG is enabled. Private security keys such as the Long Term Key will be printed out. diff --git a/subsys/bluetooth/crypto/Kconfig b/subsys/bluetooth/crypto/Kconfig index ccf5a8b641b..a59979730f0 100644 --- a/subsys/bluetooth/crypto/Kconfig +++ b/subsys/bluetooth/crypto/Kconfig @@ -3,8 +3,10 @@ config BT_CRYPTO bool - select TINYCRYPT - select TINYCRYPT_AES - select TINYCRYPT_AES_CMAC + select TINYCRYPT if !BT_USE_PSA_API + select TINYCRYPT_AES if !BT_USE_PSA_API + select TINYCRYPT_AES_CMAC if !BT_USE_PSA_API + select PSA_WANT_KEY_TYPE_AES if BT_USE_PSA_API + select PSA_WANT_ALG_CMAC if BT_USE_PSA_API help This option enables the Bluetooth Cryptographic Toolbox. diff --git a/subsys/bluetooth/crypto/bt_crypto.c b/subsys/bluetooth/crypto/bt_crypto.c index 8b098d7cc28..62a475a57d7 100644 --- a/subsys/bluetooth/crypto/bt_crypto.c +++ b/subsys/bluetooth/crypto/bt_crypto.c @@ -7,8 +7,12 @@ #include +#if defined(CONFIG_BT_USE_PSA_API) +#include "psa/crypto.h" +#else #include #include +#endif #include "common/bt_str.h" #include "bt_crypto.h" @@ -17,27 +21,6 @@ #include LOG_MODULE_REGISTER(bt_crypto); - -int bt_crypto_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, uint8_t *out) -{ - struct tc_aes_key_sched_struct sched; - struct tc_cmac_struct state; - - if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) { - return -EIO; - } - - if (tc_cmac_update(&state, in, len) == TC_CRYPTO_FAIL) { - return -EIO; - } - - if (tc_cmac_final(out, &state) == TC_CRYPTO_FAIL) { - return -EIO; - } - - return 0; -} - int bt_crypto_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, uint8_t z, uint8_t res[16]) { uint8_t xs[16]; diff --git a/subsys/bluetooth/crypto/bt_crypto_psa.c b/subsys/bluetooth/crypto/bt_crypto_psa.c new file mode 100644 index 00000000000..8e92bc9ec69 --- /dev/null +++ b/subsys/bluetooth/crypto/bt_crypto_psa.c @@ -0,0 +1,46 @@ +/* Copyright (c) 2022 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include "psa/crypto.h" + +#include "common/bt_str.h" +#include "bt_crypto.h" + +#define LOG_LEVEL CONFIG_BT_CRYPTO_LOG_LEVEL +#include +LOG_MODULE_DECLARE(bt_crypto); + +int bt_crypto_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, uint8_t *out) +{ + psa_key_id_t key_id; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + size_t out_size; + psa_status_t status, destroy_status; + + psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attr, 128); + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_MESSAGE | + PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&key_attr, PSA_ALG_CMAC); + + status = psa_import_key(&key_attr, key, 16, &key_id); + if (status != PSA_SUCCESS) { + LOG_ERR("Failed to import AES key %d", status); + return -EIO; + } + + status = psa_mac_compute(key_id, PSA_ALG_CMAC, in, len, out, 16, &out_size); + destroy_status = psa_destroy_key(key_id); + if ((status != PSA_SUCCESS) || (destroy_status != PSA_SUCCESS)) { + LOG_ERR("Failed to compute MAC %d", status); + return -EIO; + } + + return 0; +} diff --git a/subsys/bluetooth/crypto/bt_crypto_tc.c b/subsys/bluetooth/crypto/bt_crypto_tc.c new file mode 100644 index 00000000000..95160d55dfd --- /dev/null +++ b/subsys/bluetooth/crypto/bt_crypto_tc.c @@ -0,0 +1,34 @@ +/* Copyright (c) 2022 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include +#include + +#include "common/bt_str.h" +#include "bt_crypto.h" + +int bt_crypto_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, uint8_t *out) +{ + struct tc_aes_key_sched_struct sched; + struct tc_cmac_struct state; + + if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) { + return -EIO; + } + + if (tc_cmac_update(&state, in, len) == TC_CRYPTO_FAIL) { + return -EIO; + } + + if (tc_cmac_final(out, &state) == TC_CRYPTO_FAIL) { + return -EIO; + } + + return 0; +} diff --git a/tests/bluetooth/bt_crypto/testcase.yaml b/tests/bluetooth/bt_crypto/testcase.yaml index 430d763d0cb..ba933462590 100644 --- a/tests/bluetooth/bt_crypto/testcase.yaml +++ b/tests/bluetooth/bt_crypto/testcase.yaml @@ -12,3 +12,19 @@ tests: integration_platforms: - native_sim tags: bluetooth + bluetooth.bt_crypto.psa: + filter: CONFIG_PSA_CRYPTO_CLIENT + extra_args: + - EXTRA_DTC_OVERLAY_FILE="test.overlay" + platform_allow: + - native_posix + - native_posix/native/64 + - native_sim + - native_sim/native/64 + - qemu_x86 + - qemu_cortex_m3 + - nrf5340dk/nrf5340/cpuapp/ns + - nrf52840dk/nrf52840 + integration_platforms: + - native_sim + tags: bluetooth diff --git a/tests/bluetooth/host/crypto/CMakeLists.txt b/tests/bluetooth/host/crypto/CMakeLists.txt index 1a8ae2f5a50..856b2756282 100644 --- a/tests/bluetooth/host/crypto/CMakeLists.txt +++ b/tests/bluetooth/host/crypto/CMakeLists.txt @@ -12,7 +12,7 @@ add_library(mocks STATIC mocks/hmac_prng_expects.c mocks/crypto_help_utils.c - ${ZEPHYR_BASE}/subsys/bluetooth/host/crypto.c + ${ZEPHYR_BASE}/subsys/bluetooth/host/crypto_tc.c ${ZEPHYR_BASE}/subsys/logging/log_minimal.c ${ZEPHYR_BASE}/subsys/bluetooth/common/bt_str.c ${ZEPHYR_BASE}/subsys/bluetooth/host/uuid.c