Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion subsys/bluetooth/controller/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ config BT_CTLR_LE_ENC
config BT_CTLR_ECDH
bool "Elliptic Curve Diffie-Hellman (ECDH)"
depends on BT_CTLR_ECDH_SUPPORT
default y
default y if BT_HCI_RAW
help
Enable support for Bluetooth v4.2 Elliptic Curve Diffie-Hellman
feature in the controller.
Expand Down
30 changes: 18 additions & 12 deletions subsys/bluetooth/host/crypto_psa.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ LOG_MODULE_REGISTER(bt_host_crypto);

int prng_init(void)
{
if (psa_crypto_init() != PSA_SUCCESS) {
LOG_ERR("psa_crypto_init() failed");
psa_status_t status = psa_crypto_init();

if (status != PSA_SUCCESS) {
LOG_ERR("psa_crypto_init() failed %d", status);
return -EIO;
}
return 0;
Expand All @@ -39,11 +41,13 @@ int prng_init(void)
#if defined(CONFIG_BT_HOST_CRYPTO_PRNG)
int bt_rand(void *buf, size_t len)
{
if (psa_generate_random(buf, len) == PSA_SUCCESS) {
psa_status_t status = psa_generate_random(buf, len);

if (status == PSA_SUCCESS) {
return 0;
}

LOG_ERR("psa_generate_random() failed");
LOG_ERR("psa_generate_random() failed %d", status);
return -EIO;
}
#else /* !CONFIG_BT_HOST_CRYPTO_PRNG */
Expand Down Expand Up @@ -79,8 +83,9 @@ int bt_encrypt_le(const uint8_t key[16], const uint8_t plaintext[16],
psa_set_key_bits(&attr, 128);
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&attr, PSA_ALG_ECB_NO_PADDING);
if (psa_import_key(&attr, tmp, 16, &key_id) != PSA_SUCCESS) {
LOG_ERR("Failed to import AES key");
status = psa_import_key(&attr, tmp, 16, &key_id);
if (status != PSA_SUCCESS) {
LOG_ERR("Failed to import AES key %d", status);
return -EINVAL;
}

Expand All @@ -89,12 +94,12 @@ int bt_encrypt_le(const uint8_t key[16], const uint8_t plaintext[16],
status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, tmp, 16,
enc_data, 16, &out_len);
if (status != PSA_SUCCESS) {
LOG_ERR("AES encryption failed");
LOG_ERR("AES encryption failed %d", status);
}

destroy_status = psa_destroy_key(key_id);
if (destroy_status != PSA_SUCCESS) {
LOG_ERR("Failed to destroy AES key");
LOG_ERR("Failed to destroy AES key %d", destroy_status);
}

if ((status != PSA_SUCCESS) || (destroy_status != PSA_SUCCESS)) {
Expand Down Expand Up @@ -127,20 +132,21 @@ int bt_encrypt_be(const uint8_t key[16], const uint8_t plaintext[16],
psa_set_key_bits(&attr, 128);
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&attr, PSA_ALG_ECB_NO_PADDING);
if (psa_import_key(&attr, key, 16, &key_id) != PSA_SUCCESS) {
LOG_ERR("Failed to import AES key");
status = psa_import_key(&attr, key, 16, &key_id);
if (status != PSA_SUCCESS) {
LOG_ERR("Failed to import AES key %d", status);
return -EINVAL;
}

status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING,
plaintext, 16, enc_data, 16, &out_len);
if (status != PSA_SUCCESS) {
LOG_ERR("AES encryption failed");
LOG_ERR("AES encryption failed %d", status);
}

destroy_status = psa_destroy_key(key_id);
if (destroy_status != PSA_SUCCESS) {
LOG_ERR("Failed to destroy AES key");
LOG_ERR("Failed to destroy AES key %d", destroy_status);
}

if ((status != PSA_SUCCESS) || (destroy_status != PSA_SUCCESS)) {
Expand Down
43 changes: 25 additions & 18 deletions subsys/bluetooth/host/ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ bool bt_pub_key_is_valid(const uint8_t key[BT_PUB_KEY_LEN])
return true;
}

LOG_ERR("psa_import_key() returned status %d", ret);
return false;
}

Expand All @@ -120,18 +121,20 @@ static void generate_pub_key(struct k_work *work)
uint8_t tmp_pub_key_buf[BT_PUB_KEY_LEN + 1];
size_t tmp_len;
int err;
psa_status_t ret;

set_key_attributes(&attr);

if (psa_generate_key(&attr, &key_id) != PSA_SUCCESS) {
LOG_ERR("Failed to generate ECC key");
ret = psa_generate_key(&attr, &key_id);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to generate ECC key %d", ret);
err = BT_HCI_ERR_UNSPECIFIED;
goto done;
}

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");
ret = psa_export_public_key(key_id, tmp_pub_key_buf, sizeof(tmp_pub_key_buf), &tmp_len);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to export ECC public key %d", ret);
err = BT_HCI_ERR_UNSPECIFIED;
goto done;
}
Expand All @@ -141,15 +144,16 @@ static void generate_pub_key(struct k_work *work)
*/
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");
ret = psa_export_key(key_id, ecc.private_key_be, BT_PRIV_KEY_LEN, &tmp_len);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to export ECC private key %d", ret);
err = BT_HCI_ERR_UNSPECIFIED;
goto done;
}

if (psa_destroy_key(key_id) != PSA_SUCCESS) {
LOG_ERR("Failed to destroy ECC key ID");
ret = psa_destroy_key(key_id);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to destroy ECC key ID %d", ret);
err = BT_HCI_ERR_UNSPECIFIED;
goto done;
}
Expand Down Expand Up @@ -184,6 +188,7 @@ static void generate_dh_key(struct k_work *work)

psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id;
psa_status_t ret;
/* PSA expects secp256r1 public key to start with a predefined 0x04 byte
* at the beginning the buffer.
*/
Expand All @@ -195,23 +200,25 @@ static void generate_dh_key(struct k_work *work)
const uint8_t *priv_key = (IS_ENABLED(CONFIG_BT_USE_DEBUG_KEYS) ?
debug_private_key_be :
ecc.private_key_be);
if (psa_import_key(&attr, priv_key, BT_PRIV_KEY_LEN, &key_id) != PSA_SUCCESS) {
ret = psa_import_key(&attr, priv_key, BT_PRIV_KEY_LEN, &key_id);
if (ret != PSA_SUCCESS) {
err = -EIO;
LOG_ERR("Failed to import the private key for key agreement");
LOG_ERR("Failed to import the private key for key agreement %d", ret);
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 = 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);
if (ret != PSA_SUCCESS) {
err = -EIO;
LOG_ERR("Raw key agreement failed");
LOG_ERR("Raw key agreement failed %d", ret);
goto exit;
}

if (psa_destroy_key(key_id) != PSA_SUCCESS) {
LOG_ERR("Failed to destroy the key");
ret = psa_destroy_key(key_id);
if (ret != PSA_SUCCESS) {
LOG_ERR("Failed to destroy the key %d", ret);
err = -EIO;
}

Expand Down
25 changes: 15 additions & 10 deletions subsys/bluetooth/host/gatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,29 +703,34 @@ struct gen_hash_state {
static int db_hash_setup(struct gen_hash_state *state, uint8_t *key)
{
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t ret;

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_set_key_algorithm(&key_attr, PSA_ALG_CMAC);

if (psa_import_key(&key_attr, key, 16, &(state->key)) != PSA_SUCCESS) {
LOG_ERR("Unable to import the key for AES CMAC");
ret = psa_import_key(&key_attr, key, 16, &(state->key));
if (ret != PSA_SUCCESS) {
LOG_ERR("Unable to import the key for AES CMAC %d", ret);
return -EIO;
}
state->operation = psa_mac_operation_init();
if (psa_mac_sign_setup(&(state->operation), state->key,
PSA_ALG_CMAC) != PSA_SUCCESS) {
LOG_ERR("CMAC operation init failed");

ret = psa_mac_sign_setup(&(state->operation), state->key, PSA_ALG_CMAC);
if (ret != PSA_SUCCESS) {
LOG_ERR("CMAC operation init failed %d", ret);
return -EIO;
}
return 0;
}

static int db_hash_update(struct gen_hash_state *state, uint8_t *data, size_t len)
{
if (psa_mac_update(&(state->operation), data, len) != PSA_SUCCESS) {
LOG_ERR("CMAC update failed");
psa_status_t ret = psa_mac_update(&(state->operation), data, len);

if (ret != PSA_SUCCESS) {
LOG_ERR("CMAC update failed %d", ret);
return -EIO;
}
return 0;
Expand All @@ -734,10 +739,10 @@ static int db_hash_update(struct gen_hash_state *state, uint8_t *data, size_t le
static int db_hash_finish(struct gen_hash_state *state)
{
size_t mac_length;
psa_status_t ret = psa_mac_sign_finish(&(state->operation), db_hash.hash, 16, &mac_length);

if (psa_mac_sign_finish(&(state->operation), db_hash.hash, 16,
&mac_length) != PSA_SUCCESS) {
LOG_ERR("CMAC finish failed");
if (ret != PSA_SUCCESS) {
LOG_ERR("CMAC finish failed %d", ret);
return -EIO;
}
return 0;
Expand Down
Loading