mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
fix(ble/bluedroid): Replaced the psa_ api with the mbedtls_ api
This commit is contained in:
@@ -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"
|
||||
@@ -782,15 +782,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++) {
|
||||
@@ -798,23 +810,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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# BLE Encrypted Advertising Data Central Example (Bluedroid)
|
||||
|
||||
@@ -195,7 +195,7 @@ This central example works with the `enc_adv_data_prph` peripheral example to de
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* Two development boards with ESP32/ESP32-C2/ESP32-C3/ESP32-C5/ESP32-C6/ESP32-C61/ESP32-H2/ESP32-S3 SoC
|
||||
* Two development boards with ESP32/ESP32-C2/ESP32-C3/ESP32-C6/ESP32-H2/ESP32-S3 SoC
|
||||
* USB cables for power supply and programming
|
||||
|
||||
### Setup
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# BLE Encrypted Advertising Data Peripheral Example (Bluedroid)
|
||||
|
||||
@@ -104,7 +104,7 @@ Encrypted Payload Detail:
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with ESP32/ESP32-C2/ESP32-C3/ESP32-C5/ESP32-C6/ESP32-C61/ESP32-H2/ESP32-S3 SoC
|
||||
* A development board with ESP32/ESP32-C2/ESP32-C3/ESP32-C6/ESP32-H2/ESP32-S3 SoC
|
||||
* A USB cable for power supply and programming
|
||||
|
||||
### Configure the project
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user