diff --git a/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index e6cbc9c02b6..3580dde427b 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -23,7 +23,7 @@ #include "stack/l2c_api.h" #include "smp_int.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) -#include "psa/crypto.h" +#include "mbedtls/ecp.h" #elif (SMP_CRYPTO_TINYCRYPT == TRUE) #include "tinycrypt/ecc_dh.h" #include "tinycrypt/ecc.h" @@ -786,15 +786,27 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) #if (SMP_CRYPTO_MBEDTLS == TRUE) { /* - * PSA Crypto validates the public key when importing. - * We try to import the peer's public key as a ECC public key. - * If import fails, the key is invalid. + * mbedTLS validates the public key using mbedtls_ecp_check_pubkey. */ - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; + mbedtls_ecp_group grp = {0}; + mbedtls_ecp_point pt = {0}; + int rc; UINT8 pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&pt); + + /* Load the group */ + rc = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); + if (rc != 0) { + SMP_TRACE_ERROR("%s, Invalid Public key. mbedtls_ecp_group_load failed: %d\n", __func__, rc); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + reason = SMP_INVALID_PARAMETERS; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } + /* Construct peer public key in uncompressed format (0x04 || X || Y) */ pub_be[0] = 0x04; for (int i = 0; i < BT_OCTET32_LEN; i++) { @@ -802,23 +814,31 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) pub_be[33 + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i]; } - /* Try to import as public key - PSA will validate it's on the curve */ - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&key_attributes, 256); - psa_set_key_usage_flags(&key_attributes, 0); /* No usage needed, just validating */ + /* Read public key */ + rc = mbedtls_ecp_point_read_binary(&grp, &pt, pub_be, sizeof(pub_be)); + if (rc != 0) { + SMP_TRACE_ERROR("%s, Invalid Public key. mbedtls_ecp_point_read_binary failed: %d\n", __func__, rc); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + reason = SMP_INVALID_PARAMETERS; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); + return; + } - status = psa_import_key(&key_attributes, pub_be, sizeof(pub_be), &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("%s, Invalid Public key. psa_import_key failed: %d\n", __func__, status); + /* Validate public key - check if it's on the curve */ + rc = mbedtls_ecp_check_pubkey(&grp, &pt); + if (rc != 0) { + SMP_TRACE_ERROR("%s, Invalid Public key. mbedtls_ecp_check_pubkey failed: %d\n", __func__, rc); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); reason = SMP_INVALID_PARAMETERS; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason); return; } /* Key is valid, clean up */ - psa_destroy_key(key_id); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); } #elif (SMP_CRYPTO_TINYCRYPT == TRUE) { diff --git a/components/bt/host/bluedroid/stack/smp/smp_cmac.c b/components/bt/host/bluedroid/stack/smp/smp_cmac.c index fd10e50760e..b097a05d235 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_cmac.c +++ b/components/bt/host/bluedroid/stack/smp/smp_cmac.c @@ -33,7 +33,8 @@ #include "smp_int.h" #include "stack/hcimsgs.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) -#include "psa/crypto.h" +#include "mbedtls/cipher.h" +#include "mbedtls/cmac.h" #elif (SMP_CRYPTO_TINYCRYPT == TRUE) #include "tinycrypt/aes.h" #include "tinycrypt/cmac_mode.h" @@ -307,92 +308,65 @@ BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length, #if (SMP_CRYPTO_MBEDTLS == TRUE) { /* - * PSA Crypto CMAC implementation. - * Bluedroid uses little-endian, PSA uses big-endian. - * We reverse the key and input, then reverse the output. + * mbedTLS CMAC implementation. + * Bluedroid and mbedTLS both use little-endian, so no byte order conversion needed. */ - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; - UINT8 key_be[BT_OCTET16_LEN]; - UINT8 *input_be = NULL; - UINT8 mac_be[BT_OCTET16_LEN]; - size_t mac_len = 0; + mbedtls_cipher_context_t ctx = {0}; + const mbedtls_cipher_info_t *cipher_info; + int rc; - SMP_TRACE_DEBUG("AES128_CMAC (PSA) started, length = %d", length); + SMP_TRACE_DEBUG("AES128_CMAC (mbedTLS) started, length = %d", length); - /* Convert key from little-endian to big-endian */ - for (int i = 0; i < BT_OCTET16_LEN; i++) { - key_be[i] = key[BT_OCTET16_LEN - 1 - i]; + mbedtls_cipher_init(&ctx); + + cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); + if (cipher_info == NULL) { + SMP_TRACE_ERROR("mbedtls_cipher_info_from_type failed"); + mbedtls_cipher_free(&ctx); + return FALSE; } - /* Allocate and convert input from little-endian to big-endian */ - if (length > 0) { - input_be = (UINT8 *)osi_malloc(length); - if (input_be == NULL) { - SMP_TRACE_ERROR("No resources for input_be"); + rc = mbedtls_cipher_setup(&ctx, cipher_info); + if (rc != 0) { + SMP_TRACE_ERROR("mbedtls_cipher_setup failed: %d", rc); + mbedtls_cipher_free(&ctx); + return FALSE; + } + + rc = mbedtls_cipher_cmac_starts(&ctx, key, 128); + if (rc != 0) { + SMP_TRACE_ERROR("mbedtls_cipher_cmac_starts failed: %d", rc); + mbedtls_cipher_free(&ctx); + return FALSE; + } + + if (length > 0 && input != NULL) { + rc = mbedtls_cipher_cmac_update(&ctx, input, length); + if (rc != 0) { + SMP_TRACE_ERROR("mbedtls_cipher_cmac_update failed: %d", rc); + mbedtls_cipher_free(&ctx); return FALSE; } - for (UINT16 i = 0; i < length; i++) { - input_be[i] = input[length - 1 - i]; - } } - /* Import the key */ - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE); - psa_set_key_algorithm(&key_attributes, PSA_ALG_CMAC); - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&key_attributes, 128); + UINT8 mac[BT_OCTET16_LEN]; + rc = mbedtls_cipher_cmac_finish(&ctx, mac); + mbedtls_cipher_free(&ctx); - status = psa_import_key(&key_attributes, key_be, BT_OCTET16_LEN, &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("psa_import_key failed: %d", status); - if (input_be) osi_free(input_be); + if (rc != 0) { + SMP_TRACE_ERROR("mbedtls_cipher_cmac_finish failed: %d", rc); + /* Clear sensitive data from stack */ + memset(mac, 0, sizeof(mac)); return FALSE; } - /* Setup MAC operation */ - status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("psa_mac_sign_setup failed: %d", status); - psa_destroy_key(key_id); - if (input_be) osi_free(input_be); - return FALSE; - } - - /* Update with input data */ - if (length > 0 && input_be != NULL) { - status = psa_mac_update(&operation, input_be, length); - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("psa_mac_update failed: %d", status); - psa_mac_abort(&operation); - psa_destroy_key(key_id); - osi_free(input_be); - return FALSE; - } - osi_free(input_be); - } - - /* Finish and get MAC */ - status = psa_mac_sign_finish(&operation, mac_be, sizeof(mac_be), &mac_len); - psa_destroy_key(key_id); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("psa_mac_sign_finish failed: %d", status); - psa_mac_abort(&operation); - return FALSE; - } - - /* Convert MAC from big-endian to little-endian and truncate to tlen bytes */ + /* Truncate to tlen bytes */ for (UINT16 i = 0; i < tlen && i < BT_OCTET16_LEN; i++) { - p_signature[i] = mac_be[BT_OCTET16_LEN - 1 - i]; + p_signature[i] = mac[i]; } /* Clear sensitive data from stack */ - memset(key_be, 0, sizeof(key_be)); + memset(mac, 0, sizeof(mac)); ret = TRUE; } diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index ee57dcad626..9c0fcfd52a3 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -35,7 +35,18 @@ #include "btm_ble_int.h" #include "stack/hcimsgs.h" #if (SMP_CRYPTO_MBEDTLS == TRUE) -#include "psa/crypto.h" +#include "mbedtls/aes.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/ecp.h" +#include "esp_random.h" + +/* Random number generator function for mbedTLS ECP operations */ +static int smp_mbedtls_rng(void *ctx, unsigned char *output, size_t len) +{ + (void)ctx; /* Unused parameter */ + esp_fill_random(output, len); + return 0; +} #elif (SMP_CRYPTO_TINYCRYPT == TRUE) #include "tinycrypt/aes.h" #include "tinycrypt/cmac_mode.h" @@ -206,31 +217,28 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len, #if (SMP_CRYPTO_MBEDTLS == TRUE) { - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - size_t output_len = 0; + mbedtls_aes_context ctx = {0}; + int rc; - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT); - 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); + mbedtls_aes_init(&ctx); - status = psa_import_key(&key_attributes, p_rev_key, SMP_ENCRYT_KEY_SIZE, &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __func__, status); + rc = mbedtls_aes_setkey_enc(&ctx, p_rev_key, 128); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_aes_setkey_enc failed: %d\n", __func__, rc); + mbedtls_aes_free(&ctx); + /* Clear sensitive data before freeing */ + memset(p_start, 0, SMP_ENCRYT_DATA_SIZE * 4); osi_free(p_start); return FALSE; } - status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, p_rev_data, - SMP_ENCRYT_DATA_SIZE, p_rev_output, SMP_ENCRYT_DATA_SIZE, &output_len); - psa_destroy_key(key_id); + rc = mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, p_rev_data, p_rev_output); + mbedtls_aes_free(&ctx); - if (status != PSA_SUCCESS || output_len != SMP_ENCRYT_DATA_SIZE) { - SMP_TRACE_ERROR("%s psa_cipher_encrypt failed: %d\n", __func__, status); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_aes_crypt_ecb failed: %d\n", __func__, rc); + /* Clear sensitive data before freeing */ + memset(p_start, 0, SMP_ENCRYT_DATA_SIZE * 4); osi_free(p_start); return FALSE; } @@ -1200,37 +1208,48 @@ void smp_process_private_key(tSMP_CB *p_cb) memcpy(p_cb->local_random, p_loc_oob->randomizer, BT_OCTET16_LEN); } else { #if (SMP_CRYPTO_MBEDTLS == TRUE) - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - UINT8 priv_be[BT_OCTET32_LEN]; - UINT8 pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ - size_t pub_len = 0; + mbedtls_ecp_keypair keypair = {0}; + int rc; + size_t olen; - /* Convert private key from little-endian to big-endian */ - for (int i = 0; i < BT_OCTET32_LEN; i++) { - priv_be[i] = p_cb->private_key[BT_OCTET32_LEN - 1 - i]; + mbedtls_ecp_keypair_init(&keypair); + + /* Load the group */ + rc = mbedtls_ecp_group_load(&keypair.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_group_load failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; } - /* Import the private key */ - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&key_attributes, 256); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT); - - status = psa_import_key(&key_attributes, priv_be, BT_OCTET32_LEN, &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __FUNCTION__, status); - goto psa_pubkey_cleanup; + /* Import private key (little-endian) */ + rc = mbedtls_mpi_read_binary(&keypair.MBEDTLS_PRIVATE(d), p_cb->private_key, BT_OCTET32_LEN); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_mpi_read_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; } - /* Export public key */ - status = psa_export_public_key(key_id, pub_be, sizeof(pub_be), &pub_len); - if (status != PSA_SUCCESS || pub_len != (BT_OCTET32_LEN + BT_OCTET32_LEN + 1)) { - SMP_TRACE_ERROR("%s psa_export_public_key failed: %d\n", __FUNCTION__, status); - goto psa_pubkey_cleanup; + /* Validate private key */ + rc = mbedtls_ecp_check_privkey(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(d)); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_check_privkey failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; + } + + /* Compute public key from private key */ + /* mbedtls_ecp_keypair_calc_public requires a non-NULL RNG function for side-channel protection */ + rc = mbedtls_ecp_keypair_calc_public(&keypair, smp_mbedtls_rng, NULL); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_keypair_calc_public failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; + } + + /* Export public key in uncompressed format: 0x04 || X || Y */ + UINT8 pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; + rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), + MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, pub_be, sizeof(pub_be)); + if (rc != 0 || olen != sizeof(pub_be)) { + SMP_TRACE_ERROR("%s mbedtls_ecp_point_write_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_pubkey_cleanup; } /* Convert X and Y from big-endian to little-endian */ @@ -1240,10 +1259,10 @@ void smp_process_private_key(tSMP_CB *p_cb) p_cb->loc_publ_key.y[i] = pub_be[33 + BT_OCTET32_LEN - 1 - i]; } -psa_pubkey_cleanup: - psa_destroy_key(key_id); - /* Clear sensitive data from stack */ - memset(priv_be, 0, sizeof(priv_be)); +mbedtls_pubkey_cleanup: + /* Clear sensitive data - mbedtls_ecp_keypair_free will zero the private key */ + mbedtls_ecp_keypair_free(&keypair); + /* Note: pub_be contains public key data, no need to clear */ #elif (SMP_CRYPTO_TINYCRYPT == TRUE) { UINT8 pub_key[64]; /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */ @@ -1312,31 +1331,30 @@ void smp_compute_dhkey (tSMP_CB *p_cb) SMP_TRACE_DEBUG ("%s\n", __FUNCTION__); #if (SMP_CRYPTO_MBEDTLS == TRUE) - psa_status_t status; - psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - UINT8 priv_be[BT_OCTET32_LEN]; + mbedtls_ecp_group grp = {0}; + mbedtls_ecp_point Q = {0}; + mbedtls_mpi d = {0}; + mbedtls_mpi z = {0}; + int rc; UINT8 peer_pub_be[BT_OCTET32_LEN + BT_OCTET32_LEN + 1]; /* 0x04 || X (32 bytes) || Y (32 bytes) */ - UINT8 shared_secret[BT_OCTET32_LEN]; - size_t output_len = 0; - /* Convert private key from little-endian to big-endian */ - for (int i = 0; i < BT_OCTET32_LEN; i++) { - priv_be[i] = p_cb->private_key[BT_OCTET32_LEN - 1 - i]; + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&Q); + mbedtls_mpi_init(&d); + mbedtls_mpi_init(&z); + + /* Load the group */ + rc = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_group_load failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; } - /* Import the private key */ - psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&key_attributes, 256); - psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - - status = psa_import_key(&key_attributes, priv_be, BT_OCTET32_LEN, &key_id); - psa_reset_key_attributes(&key_attributes); - - if (status != PSA_SUCCESS) { - SMP_TRACE_ERROR("%s psa_import_key failed: %d\n", __FUNCTION__, status); - goto psa_dhkey_cleanup; + /* Import private key (little-endian) */ + rc = mbedtls_mpi_read_binary(&d, p_cb->private_key, BT_OCTET32_LEN); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_mpi_read_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; } /* Construct peer public key in uncompressed format: 0x04 || X || Y */ @@ -1346,12 +1364,34 @@ void smp_compute_dhkey (tSMP_CB *p_cb) peer_pub_be[33 + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i]; } + /* Read peer public key */ + rc = mbedtls_ecp_point_read_binary(&grp, &Q, peer_pub_be, sizeof(peer_pub_be)); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_point_read_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; + } + + /* Validate peer public key */ + rc = mbedtls_ecp_check_pubkey(&grp, &Q); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecp_check_pubkey failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; + } + /* Compute ECDH shared secret */ - status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, peer_pub_be, sizeof(peer_pub_be), - shared_secret, sizeof(shared_secret), &output_len); - if (status != PSA_SUCCESS || output_len != BT_OCTET32_LEN) { - SMP_TRACE_ERROR("%s psa_raw_key_agreement failed: %d\n", __FUNCTION__, status); - goto psa_dhkey_cleanup; + /* mbedtls_ecdh_compute_shared requires a non-NULL RNG function for side-channel protection */ + rc = mbedtls_ecdh_compute_shared(&grp, &z, &Q, &d, smp_mbedtls_rng, NULL); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_ecdh_compute_shared failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; + } + + /* Export shared secret (big-endian) and convert to little-endian for DHKey */ + UINT8 shared_secret[BT_OCTET32_LEN]; + rc = mbedtls_mpi_write_binary(&z, shared_secret, BT_OCTET32_LEN); + if (rc != 0) { + SMP_TRACE_ERROR("%s mbedtls_mpi_write_binary failed: %d\n", __FUNCTION__, rc); + goto mbedtls_dhkey_cleanup; } /* Convert shared secret from big-endian to little-endian for DHKey */ @@ -1359,11 +1399,15 @@ void smp_compute_dhkey (tSMP_CB *p_cb) p_cb->dhkey[i] = shared_secret[BT_OCTET32_LEN - 1 - i]; } -psa_dhkey_cleanup: - psa_destroy_key(key_id); +mbedtls_dhkey_cleanup: + /* Clear sensitive data - mbedtls_mpi_free will zero the memory */ + mbedtls_mpi_free(&z); + mbedtls_mpi_free(&d); + mbedtls_ecp_point_free(&Q); + mbedtls_ecp_group_free(&grp); /* Clear sensitive data from stack */ - memset(priv_be, 0, sizeof(priv_be)); memset(shared_secret, 0, sizeof(shared_secret)); + /* Note: peer_pub_be contains public key data, no need to clear */ #elif (SMP_CRYPTO_TINYCRYPT == TRUE) { UINT8 priv_be[BT_OCTET32_LEN]; diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c index 7303c027b2b..92420dd4060 100644 --- a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_cent/main/ble_ead.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ #include "tinycrypt/ccm_mode.h" #include "tinycrypt/constants.h" #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) -#include "psa/crypto.h" +#include "mbedtls/ccm.h" #else #error "Please select either CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT or CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS" #endif @@ -129,11 +129,8 @@ static int ble_aes_ccm_encrypt(const uint8_t *key, const uint8_t *nonce, return 0; #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) - psa_status_t status; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); - size_t output_length = 0; + mbedtls_ccm_context ctx = {0}; + int ret; /* Validate inputs */ if (key == NULL || nonce == NULL || ciphertext == NULL) { @@ -141,43 +138,30 @@ static int ble_aes_ccm_encrypt(const uint8_t *key, const uint8_t *nonce, return -1; } - /* Set key attributes */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + mbedtls_ccm_init(&ctx); - /* Import key */ - status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_import_key failed: %d", status); - psa_reset_key_attributes(&attributes); + /* Set encryption key */ + ret = mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, BLE_EAD_KEY_SIZE * 8); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_setkey failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - psa_reset_key_attributes(&attributes); /* Encrypt and authenticate */ - /* PSA AEAD encrypt outputs: ciphertext || tag */ - status = psa_aead_encrypt(key_id, alg, - nonce, BLE_EAD_NONCE_SIZE, - aad, aad_len, - plaintext, plaintext_len, - ciphertext, plaintext_len + tag_len, - &output_length); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_aead_encrypt failed: %d", status); - psa_destroy_key(key_id); + /* mbedtls_ccm_encrypt_and_tag outputs: ciphertext || tag */ + ret = mbedtls_ccm_encrypt_and_tag(&ctx, plaintext_len, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + plaintext, ciphertext, + ciphertext + plaintext_len, tag_len); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_encrypt_and_tag failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - if (output_length != plaintext_len + tag_len) { - ESP_LOGE(TAG, "psa_aead_encrypt output length mismatch: expected %zu, got %zu", - plaintext_len + tag_len, output_length); - psa_destroy_key(key_id); - return -1; - } - - psa_destroy_key(key_id); + mbedtls_ccm_free(&ctx); return 0; #else #error "No crypto library selected" @@ -253,11 +237,8 @@ static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, return 0; #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) - psa_status_t status; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); - size_t output_length = 0; + mbedtls_ccm_context ctx = {0}; + int ret; /* ciphertext_len here includes both ciphertext and tag */ size_t plaintext_len; @@ -275,44 +256,31 @@ static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, plaintext_len = ciphertext_len - tag_len; - /* Set key attributes */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + mbedtls_ccm_init(&ctx); - /* Import key */ - status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_import_key failed: %d", status); - psa_reset_key_attributes(&attributes); + /* Set decryption key */ + ret = mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, BLE_EAD_KEY_SIZE * 8); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_setkey failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - psa_reset_key_attributes(&attributes); /* Decrypt and verify */ - /* PSA AEAD decrypt expects: ciphertext || tag */ + /* mbedtls_ccm_auth_decrypt expects: ciphertext || tag */ /* ciphertext_len here already includes tag length */ - status = psa_aead_decrypt(key_id, alg, - nonce, BLE_EAD_NONCE_SIZE, - aad, aad_len, - ciphertext, ciphertext_len, - plaintext, plaintext_len, - &output_length); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_aead_decrypt failed: %d", status); - psa_destroy_key(key_id); + ret = mbedtls_ccm_auth_decrypt(&ctx, plaintext_len, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + ciphertext, plaintext, + ciphertext + plaintext_len, tag_len); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_auth_decrypt failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - if (output_length != plaintext_len) { - ESP_LOGE(TAG, "psa_aead_decrypt output length mismatch: expected %zu, got %zu", - plaintext_len, output_length); - psa_destroy_key(key_id); - return -1; - } - - psa_destroy_key(key_id); + mbedtls_ccm_free(&ctx); return 0; #else #error "No crypto library selected" @@ -407,7 +375,7 @@ int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], /* Ciphertext + MIC follows the randomizer */ ciphertext = &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE]; - /* ciphertext_len includes both ciphertext and MIC (tag) for PSA API */ + /* ciphertext_len includes both ciphertext and MIC (tag) for mbedTLS API */ ciphertext_len = encrypted_payload_size - BLE_EAD_RANDOMIZER_SIZE; /* Generate nonce from randomizer and IV */ diff --git a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c index b3e1dcc8f87..cc0abeca1dc 100644 --- a/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c +++ b/examples/bluetooth/bluedroid/ble/ble_enc_adv_data/enc_adv_data_prph/main/ble_ead.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ #include "tinycrypt/ccm_mode.h" #include "tinycrypt/constants.h" #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) -#include "psa/crypto.h" +#include "mbedtls/ccm.h" #else #error "Please select either CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT or CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS" #endif @@ -129,49 +129,33 @@ static int ble_aes_ccm_encrypt(const uint8_t *key, const uint8_t *nonce, return 0; #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) - psa_status_t status; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); - size_t output_length = 0; + mbedtls_ccm_context ctx = {0}; + int ret; - /* Set key attributes */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + mbedtls_ccm_init(&ctx); - /* Import key */ - status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_import_key failed: %d", status); - psa_reset_key_attributes(&attributes); + /* Set encryption key */ + ret = mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, BLE_EAD_KEY_SIZE * 8); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_setkey failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - psa_reset_key_attributes(&attributes); /* Encrypt and authenticate */ - /* PSA AEAD encrypt outputs: ciphertext || tag */ - status = psa_aead_encrypt(key_id, alg, - nonce, BLE_EAD_NONCE_SIZE, - aad, aad_len, - plaintext, plaintext_len, - ciphertext, plaintext_len + tag_len, - &output_length); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_aead_encrypt failed: %d", status); - psa_destroy_key(key_id); + /* mbedtls_ccm_encrypt_and_tag outputs: ciphertext || tag */ + ret = mbedtls_ccm_encrypt_and_tag(&ctx, plaintext_len, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + plaintext, ciphertext, + ciphertext + plaintext_len, tag_len); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_encrypt_and_tag failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - if (output_length != plaintext_len + tag_len) { - ESP_LOGE(TAG, "psa_aead_encrypt output length mismatch: expected %zu, got %zu", - plaintext_len + tag_len, output_length); - psa_destroy_key(key_id); - return -1; - } - - psa_destroy_key(key_id); + mbedtls_ccm_free(&ctx); return 0; #else #error "No crypto library selected" @@ -247,11 +231,8 @@ static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, return 0; #elif defined(CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS) - psa_status_t status; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_len); - size_t output_length = 0; + mbedtls_ccm_context ctx = {0}; + int ret; /* ciphertext_len here includes both ciphertext and tag */ size_t plaintext_len; @@ -269,43 +250,30 @@ static int ble_aes_ccm_decrypt(const uint8_t *key, const uint8_t *nonce, plaintext_len = ciphertext_len - tag_len; - /* Set key attributes */ - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); - psa_set_key_algorithm(&attributes, alg); - psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); - psa_set_key_bits(&attributes, BLE_EAD_KEY_SIZE * 8); + mbedtls_ccm_init(&ctx); - /* Import key */ - status = psa_import_key(&attributes, key, BLE_EAD_KEY_SIZE, &key_id); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_import_key failed: %d", status); - psa_reset_key_attributes(&attributes); + /* Set decryption key */ + ret = mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, BLE_EAD_KEY_SIZE * 8); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_setkey failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - psa_reset_key_attributes(&attributes); /* Decrypt and verify */ - /* PSA AEAD decrypt expects: ciphertext || tag */ - status = psa_aead_decrypt(key_id, alg, - nonce, BLE_EAD_NONCE_SIZE, - aad, aad_len, - ciphertext, ciphertext_len, - plaintext, plaintext_len, - &output_length); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "psa_aead_decrypt failed: %d", status); - psa_destroy_key(key_id); + /* mbedtls_ccm_auth_decrypt expects: ciphertext || tag */ + ret = mbedtls_ccm_auth_decrypt(&ctx, plaintext_len, + nonce, BLE_EAD_NONCE_SIZE, + aad, aad_len, + ciphertext, plaintext, + ciphertext + plaintext_len, tag_len); + if (ret != 0) { + ESP_LOGE(TAG, "mbedtls_ccm_auth_decrypt failed: %d", ret); + mbedtls_ccm_free(&ctx); return -1; } - if (output_length != plaintext_len) { - ESP_LOGE(TAG, "psa_aead_decrypt output length mismatch: expected %zu, got %zu", - plaintext_len, output_length); - psa_destroy_key(key_id); - return -1; - } - - psa_destroy_key(key_id); + mbedtls_ccm_free(&ctx); return 0; #else #error "No crypto library selected" @@ -400,7 +368,7 @@ int ble_ead_decrypt(const uint8_t session_key[BLE_EAD_KEY_SIZE], /* Ciphertext + MIC follows the randomizer */ ciphertext = &encrypted_payload[BLE_EAD_RANDOMIZER_SIZE]; - /* ciphertext_len includes both ciphertext and MIC (tag) for PSA API */ + /* ciphertext_len includes both ciphertext and MIC (tag) for mbedTLS API */ ciphertext_len = encrypted_payload_size - BLE_EAD_RANDOMIZER_SIZE; /* Generate nonce from randomizer and IV */