bt: hci_ecc: 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/mesh/basic/bluetooth.mesh.gatt adding a specific case using PSA. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
This commit is contained in:
parent
32b792b21f
commit
32b43564df
3 changed files with 113 additions and 11 deletions
|
|
@ -194,7 +194,7 @@ 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 BT_CRYPTO || BT_HOST_CRYPTO || BT_ECC
|
||||
depends on PSA_CRYPTO_CLIENT
|
||||
help
|
||||
Use PSA APIs instead of TinyCrypt for crypto operations
|
||||
|
|
|
|||
|
|
@ -13,10 +13,15 @@
|
|||
#include <zephyr/sys/atomic.h>
|
||||
#include <zephyr/debug/stack.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
|
||||
#if defined(CONFIG_BT_USE_PSA_API)
|
||||
#include <psa/crypto.h>
|
||||
#else /* !CONFIG_BT_USE_PSA_API */
|
||||
#include <tinycrypt/constants.h>
|
||||
#include <tinycrypt/utils.h>
|
||||
#include <tinycrypt/ecc.h>
|
||||
#include <tinycrypt/ecc_dh.h>
|
||||
#endif /* CONFIG_BT_USE_PSA_API*/
|
||||
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/buf.h>
|
||||
|
|
@ -104,6 +109,54 @@ static void send_cmd_status(uint16_t opcode, uint8_t status)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_USE_PSA_API)
|
||||
static void set_key_attributes(psa_key_attributes_t *attr)
|
||||
{
|
||||
psa_set_key_type(attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_bits(attr, 256);
|
||||
psa_set_key_usage_flags(attr, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_algorithm(attr, PSA_ALG_ECDH);
|
||||
}
|
||||
|
||||
static uint8_t generate_keys(void)
|
||||
{
|
||||
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id;
|
||||
uint8_t tmp_pub_key_buf[BT_PUB_KEY_LEN + 1];
|
||||
size_t tmp_len;
|
||||
|
||||
set_key_attributes(&attr);
|
||||
|
||||
if (psa_generate_key(&attr, &key_id) != PSA_SUCCESS) {
|
||||
LOG_ERR("Failed to generate ECC key");
|
||||
return BT_HCI_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if (psa_export_public_key(key_id, tmp_pub_key_buf, sizeof(tmp_pub_key_buf),
|
||||
&tmp_len) != PSA_SUCCESS) {
|
||||
LOG_ERR("Failed to export ECC public key");
|
||||
return BT_HCI_ERR_UNSPECIFIED;
|
||||
}
|
||||
/* secp256r1 PSA exported public key has an extra 0x04 predefined byte at
|
||||
* the beginning of the buffer which is not part of the coordinate so
|
||||
* we remove that.
|
||||
*/
|
||||
memcpy(ecc.public_key_be, &tmp_pub_key_buf[1], BT_PUB_KEY_LEN);
|
||||
|
||||
if (psa_export_key(key_id, ecc.private_key_be, BT_PRIV_KEY_LEN,
|
||||
&tmp_len) != PSA_SUCCESS) {
|
||||
LOG_ERR("Failed to export ECC private key");
|
||||
return BT_HCI_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if (psa_destroy_key(key_id) != PSA_SUCCESS) {
|
||||
LOG_ERR("Failed to destroy ECC key ID");
|
||||
return BT_HCI_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static uint8_t generate_keys(void)
|
||||
{
|
||||
do {
|
||||
|
|
@ -125,6 +178,7 @@ static uint8_t generate_keys(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_USE_PSA_API */
|
||||
|
||||
static void emulate_le_p256_public_key_cmd(void)
|
||||
{
|
||||
|
|
@ -176,21 +230,55 @@ static void emulate_le_generate_dhkey(void)
|
|||
struct bt_hci_evt_le_meta_event *meta;
|
||||
struct bt_hci_evt_hdr *hdr;
|
||||
struct net_buf *buf;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
bool use_debug = atomic_test_bit(flags, USE_DEBUG_KEY);
|
||||
|
||||
#if defined(CONFIG_BT_USE_PSA_API)
|
||||
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id;
|
||||
/* PSA expects secp256r1 public key to start with a predefined 0x04 byte
|
||||
* at the beginning the buffer.
|
||||
*/
|
||||
uint8_t tmp_pub_key_buf[BT_PUB_KEY_LEN + 1] = { 0x04 };
|
||||
size_t tmp_len;
|
||||
|
||||
set_key_attributes(&attr);
|
||||
|
||||
if (psa_import_key(&attr, use_debug ? debug_private_key_be : ecc.private_key_be,
|
||||
BT_PRIV_KEY_LEN, &key_id) != PSA_SUCCESS) {
|
||||
ret = -EIO;
|
||||
LOG_ERR("Failed to import the private key for key agreement");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(&tmp_pub_key_buf[1], ecc.public_key_be, BT_PUB_KEY_LEN);
|
||||
if (psa_raw_key_agreement(PSA_ALG_ECDH, key_id, tmp_pub_key_buf,
|
||||
sizeof(tmp_pub_key_buf), ecc.dhkey_be, BT_DH_KEY_LEN,
|
||||
&tmp_len) != PSA_SUCCESS) {
|
||||
ret = -EIO;
|
||||
LOG_ERR("Raw key agreement failed");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (psa_destroy_key(key_id) != PSA_SUCCESS) {
|
||||
LOG_ERR("Failed to destroy the key");
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_BT_USE_PSA_API */
|
||||
ret = uECC_valid_public_key(ecc.public_key_be, &curve_secp256r1);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("public key is not valid (ret %d)", ret);
|
||||
ret = TC_CRYPTO_FAIL;
|
||||
} else {
|
||||
bool use_debug = atomic_test_bit(flags, USE_DEBUG_KEY);
|
||||
|
||||
ret = uECC_shared_secret(ecc.public_key_be,
|
||||
use_debug ? debug_private_key_be :
|
||||
ecc.private_key_be,
|
||||
ecc.dhkey_be, &curve_secp256r1);
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
ret = uECC_shared_secret(ecc.public_key_be,
|
||||
use_debug ? debug_private_key_be : ecc.private_key_be,
|
||||
ecc.dhkey_be, &curve_secp256r1);
|
||||
ret = (ret == TC_CRYPTO_FAIL) ? -EIO : 0;
|
||||
#endif /* CONFIG_BT_USE_PSA_API */
|
||||
|
||||
exit:
|
||||
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
|
||||
|
||||
hdr = net_buf_add(buf, sizeof(*hdr));
|
||||
|
|
@ -202,7 +290,7 @@ static void emulate_le_generate_dhkey(void)
|
|||
|
||||
evt = net_buf_add(buf, sizeof(*evt));
|
||||
|
||||
if (ret == TC_CRYPTO_FAIL) {
|
||||
if (ret != 0) {
|
||||
evt->status = BT_HCI_ERR_UNSPECIFIED;
|
||||
(void)memset(evt->dhkey, 0xff, sizeof(evt->dhkey));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,20 @@ tests:
|
|||
platform_allow:
|
||||
- qemu_x86
|
||||
- nrf52840dk/nrf52840
|
||||
- nrf5340dk/nrf5340/cpuapp/ns
|
||||
integration_platforms:
|
||||
- qemu_x86
|
||||
tags:
|
||||
- bluetooth
|
||||
- mesh
|
||||
bluetooth.mesh.gatt.psa:
|
||||
build_only: true
|
||||
extra_args: CONF_FILE=gatt.conf
|
||||
extra_configs:
|
||||
- CONFIG_BT_USE_PSA_API=y
|
||||
platform_allow:
|
||||
- qemu_x86
|
||||
- nrf5340dk/nrf5340/cpuapp/ns
|
||||
integration_platforms:
|
||||
- qemu_x86
|
||||
tags:
|
||||
|
|
|
|||
Loading…
Reference in a new issue