mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(ble/bluedroid): Supported Bludroid host encryption using TinyCrypt
This commit is contained in:
@@ -725,7 +725,12 @@ if(CONFIG_BT_ENABLED)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT (CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS OR CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS))
|
||||
# Compile TinyCrypt if:
|
||||
# 1. Controller uses TinyCrypt (not mbedTLS), OR
|
||||
# 2. NimBLE uses TinyCrypt (not mbedTLS), OR
|
||||
# 3. Bluedroid Host SMP uses TinyCrypt
|
||||
if(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT OR
|
||||
(NOT CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS AND NOT CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS))
|
||||
list(APPEND include_dirs
|
||||
common/tinycrypt/include
|
||||
common/tinycrypt/port
|
||||
|
||||
@@ -457,26 +457,43 @@ config BT_BLE_SMP_BOND_NVS_FLASH
|
||||
help
|
||||
This select can save SMP bonding keys to nvs flash
|
||||
|
||||
config BT_SMP_CRYPTO_MBEDTLS
|
||||
bool "Use mbedTLS for SMP cryptographic functions"
|
||||
choice BT_SMP_CRYPTO_STACK
|
||||
prompt "SMP cryptographic stack"
|
||||
depends on BT_BLE_SMP_ENABLE
|
||||
depends on !BLE_MESH
|
||||
select MBEDTLS_AES_C
|
||||
select MBEDTLS_CMAC_C
|
||||
select MBEDTLS_ECDH_C
|
||||
select MBEDTLS_ECP_C
|
||||
select MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
default n
|
||||
default BT_SMP_CRYPTO_STACK_NATIVE
|
||||
help
|
||||
If enabled, the SMP layer will use mbedTLS library for cryptographic
|
||||
operations (AES, AES-CMAC, ECDH P-256) instead of the built-in
|
||||
Bluedroid implementation. This can provide hardware acceleration
|
||||
on supported platforms and reduce code size by sharing crypto
|
||||
implementations with other components.
|
||||
Select the cryptographic library to use for SMP operations (AES, AES-CMAC, ECDH P-256).
|
||||
|
||||
Note: This option is not compatible with BLE Mesh, as BLE Mesh
|
||||
uses the native Bluedroid ECC implementation directly.
|
||||
|
||||
config BT_SMP_CRYPTO_STACK_NATIVE
|
||||
bool "Native Bluedroid implementation"
|
||||
help
|
||||
Use the built-in Bluedroid cryptographic implementation.
|
||||
This is the default option and provides compatibility with all features.
|
||||
|
||||
config BT_SMP_CRYPTO_STACK_TINYCRYPT
|
||||
bool "TinyCrypt"
|
||||
help
|
||||
Use TinyCrypt library for cryptographic operations.
|
||||
TinyCrypt is a lightweight cryptographic library designed for constrained devices.
|
||||
This can reduce code size compared to the native implementation.
|
||||
|
||||
config BT_SMP_CRYPTO_STACK_MBEDTLS
|
||||
bool "mbedTLS"
|
||||
select MBEDTLS_AES_C
|
||||
select MBEDTLS_CMAC_C
|
||||
select MBEDTLS_ECDH_C
|
||||
select MBEDTLS_ECP_C
|
||||
select MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
help
|
||||
Use mbedTLS library for cryptographic operations.
|
||||
This can provide hardware acceleration on supported platforms and reduce code size
|
||||
by sharing crypto implementations with other components.
|
||||
|
||||
endchoice
|
||||
|
||||
config BT_BLE_RPA_SUPPORTED
|
||||
bool "Update RPA to Controller"
|
||||
depends on (BT_BLE_SMP_ENABLE && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED)) # NOERROR
|
||||
|
||||
@@ -467,12 +467,24 @@
|
||||
#define UC_BT_BLE_SMP_BOND_NVS_FLASH FALSE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_SMP_CRYPTO_MBEDTLS
|
||||
#define UC_BT_SMP_CRYPTO_MBEDTLS CONFIG_BT_SMP_CRYPTO_MBEDTLS
|
||||
#ifdef CONFIG_BT_SMP_CRYPTO_STACK_NATIVE
|
||||
#define UC_BT_SMP_CRYPTO_STACK_NATIVE TRUE
|
||||
#else
|
||||
#define UC_BT_SMP_CRYPTO_STACK_NATIVE FALSE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
|
||||
#define UC_BT_SMP_CRYPTO_MBEDTLS TRUE
|
||||
#else
|
||||
#define UC_BT_SMP_CRYPTO_MBEDTLS FALSE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT
|
||||
#define UC_BT_SMP_CRYPTO_TINYCRYPT TRUE
|
||||
#else
|
||||
#define UC_BT_SMP_CRYPTO_TINYCRYPT FALSE
|
||||
#endif
|
||||
|
||||
//Device Name Maximum Length
|
||||
#ifdef CONFIG_BT_MAX_DEVICE_NAME_LEN
|
||||
#define UC_MAX_LOC_BD_NAME_LEN CONFIG_BT_MAX_DEVICE_NAME_LEN
|
||||
|
||||
@@ -517,12 +517,24 @@
|
||||
#define BLE_SMP_BOND_NVS_FLASH FALSE
|
||||
#endif
|
||||
|
||||
#if (UC_BT_SMP_CRYPTO_STACK_NATIVE)
|
||||
#define SMP_CRYPTO_STACK_NATIVE TRUE
|
||||
#else
|
||||
#define SMP_CRYPTO_STACK_NATIVE FALSE
|
||||
#endif /* UC_BT_SMP_CRYPTO_STACK_NATIVE */
|
||||
|
||||
#if (UC_BT_SMP_CRYPTO_MBEDTLS)
|
||||
#define SMP_CRYPTO_MBEDTLS TRUE
|
||||
#else
|
||||
#define SMP_CRYPTO_MBEDTLS FALSE
|
||||
#endif /* UC_BT_SMP_CRYPTO_MBEDTLS */
|
||||
|
||||
#if (UC_BT_SMP_CRYPTO_TINYCRYPT)
|
||||
#define SMP_CRYPTO_TINYCRYPT TRUE
|
||||
#else
|
||||
#define SMP_CRYPTO_TINYCRYPT FALSE
|
||||
#endif /* UC_BT_SMP_CRYPTO_TINYCRYPT */
|
||||
|
||||
#ifdef UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
#define BLE_ADV_REPORT_FLOW_CONTROL (UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP && BLE_INCLUDED)
|
||||
#endif /* UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP */
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
/* add the target configuration to allow using internal data types and compilation options */
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
|
||||
/* define if you have fast 32-bit types on your system */
|
||||
#if 1
|
||||
@@ -937,6 +937,6 @@ void bluedroid_aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char o
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
|
||||
#if 1
|
||||
# define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */
|
||||
@@ -163,6 +163,6 @@ void bluedroid_aes_decrypt_256( const unsigned char in[N_BLOCK],
|
||||
unsigned char o_key[2 * N_BLOCK] );
|
||||
#endif
|
||||
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
#endif /* AES_H */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
|
||||
#include "p_256_multprecision.h"
|
||||
|
||||
@@ -76,4 +76,4 @@ bool ECC_CheckPointIsInElliCur_P256(Point *p);
|
||||
|
||||
void p_256_init_curve(UINT32 keyLength);
|
||||
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "stack/bt_types.h"
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
|
||||
/* Type definitions */
|
||||
typedef unsigned long DWORD;
|
||||
@@ -62,4 +62,4 @@ void multiprecision_mult(DWORD *c, DWORD *a, DWORD *b, uint32_t keyLength);
|
||||
void multiprecision_fast_mod(DWORD *c, DWORD *a);
|
||||
void multiprecision_fast_mod_P256(DWORD *c, DWORD *a);
|
||||
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <string.h>
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
|
||||
#include "p_256_ecc_pp.h"
|
||||
|
||||
@@ -81,4 +81,4 @@ void p_256_init_curve(UINT32 keyLength)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <string.h>
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
|
||||
#include "p_256_ecc_pp.h"
|
||||
#include "p_256_multprecision.h"
|
||||
@@ -285,4 +285,4 @@ bool ECC_CheckPointIsInElliCur_P256(Point *p)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <string.h>
|
||||
#include "common/bt_target.h"
|
||||
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
|
||||
#include "p_256_ecc_pp.h"
|
||||
#include "p_256_multprecision.h"
|
||||
@@ -649,4 +649,4 @@ void multiprecision_inv_mod(DWORD *aminus, DWORD *u, uint32_t keyLength)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
#include "smp_int.h"
|
||||
#if (SMP_CRYPTO_MBEDTLS == TRUE)
|
||||
#include "psa/crypto.h"
|
||||
#elif (SMP_CRYPTO_TINYCRYPT == TRUE)
|
||||
#include "tinycrypt/ecc_dh.h"
|
||||
#include "tinycrypt/ecc.h"
|
||||
#include "tinycrypt/constants.h"
|
||||
#else
|
||||
#include "p_256_ecc_pp.h"
|
||||
#endif
|
||||
@@ -812,6 +816,34 @@ void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
||||
/* Key is valid, clean up */
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
#elif (SMP_CRYPTO_TINYCRYPT == TRUE)
|
||||
{
|
||||
/*
|
||||
* TinyCrypt validates the public key using uECC_valid_public_key.
|
||||
* TinyCrypt expects public key in format: X (32 bytes) || Y (32 bytes), no prefix.
|
||||
*/
|
||||
UINT8 pub_be[64]; /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */
|
||||
|
||||
/* Convert peer public key from little-endian to big-endian */
|
||||
/* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */
|
||||
for (int i = 0; i < BT_OCTET32_LEN; i++) {
|
||||
pub_be[i] = p_cb->peer_publ_key.x[BT_OCTET32_LEN - 1 - i];
|
||||
pub_be[BT_OCTET32_LEN + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i];
|
||||
}
|
||||
|
||||
/* Validate public key - TinyCrypt will check if it's on the curve */
|
||||
/* uECC_valid_public_key returns 0 if valid, negative value if invalid */
|
||||
if (uECC_valid_public_key(pub_be, uECC_secp256r1()) < 0) {
|
||||
SMP_TRACE_ERROR("%s, Invalid Public key. uECC_valid_public_key failed\n", __func__);
|
||||
reason = SMP_INVALID_PARAMETERS;
|
||||
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
|
||||
memset(pub_be, 0, sizeof(pub_be));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear sensitive data from stack */
|
||||
memset(pub_be, 0, sizeof(pub_be));
|
||||
}
|
||||
#else
|
||||
if (!ECC_CheckPointIsInElliCur_P256((Point *)&p_cb->peer_publ_key)) {
|
||||
SMP_TRACE_ERROR("%s, Invalid Public key.", __func__);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "stack/hcimsgs.h"
|
||||
|
||||
#include "stack/btu.h"
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
#include "p_256_ecc_pp.h"
|
||||
#endif
|
||||
#include "osi/allocator.h"
|
||||
@@ -53,13 +53,13 @@ void SMP_Init(void)
|
||||
{
|
||||
#if SMP_DYNAMIC_MEMORY
|
||||
smp_cb_ptr = (tSMP_CB *)osi_malloc(sizeof(tSMP_CB));
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
curve_ptr = (elliptic_curve_t *)osi_malloc(sizeof(elliptic_curve_t));
|
||||
curve_p256_ptr = (elliptic_curve_t *)osi_malloc(sizeof(elliptic_curve_t));
|
||||
#endif
|
||||
#endif
|
||||
memset(&smp_cb, 0, sizeof(tSMP_CB));
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
memset(&curve, 0, sizeof(elliptic_curve_t));
|
||||
memset(&curve_p256, 0, sizeof(elliptic_curve_t));
|
||||
#endif
|
||||
@@ -72,7 +72,7 @@ void SMP_Init(void)
|
||||
SMP_TRACE_EVENT ("%s", __FUNCTION__);
|
||||
|
||||
smp_l2cap_if_init();
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
/* initialization of P-256 parameters */
|
||||
p_256_init_curve(KEY_LENGTH_DWORDS_P256);
|
||||
#endif
|
||||
@@ -83,7 +83,7 @@ void SMP_Free(void)
|
||||
memset(&smp_cb, 0, sizeof(tSMP_CB));
|
||||
#if SMP_DYNAMIC_MEMORY
|
||||
FREE_AND_RESET(smp_cb_ptr);
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
FREE_AND_RESET(curve_ptr);
|
||||
FREE_AND_RESET(curve_p256_ptr);
|
||||
#endif
|
||||
|
||||
@@ -34,9 +34,13 @@
|
||||
#include "stack/hcimsgs.h"
|
||||
#if (SMP_CRYPTO_MBEDTLS == TRUE)
|
||||
#include "psa/crypto.h"
|
||||
#elif (SMP_CRYPTO_TINYCRYPT == TRUE)
|
||||
#include "tinycrypt/aes.h"
|
||||
#include "tinycrypt/cmac_mode.h"
|
||||
#include "tinycrypt/constants.h"
|
||||
#endif
|
||||
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
typedef struct {
|
||||
UINT8 *text;
|
||||
UINT16 len;
|
||||
@@ -50,7 +54,7 @@ const BT_OCTET16 const_Rb = {
|
||||
0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
void print128(BT_OCTET16 x, const UINT8 *key_name)
|
||||
{
|
||||
@@ -80,7 +84,7 @@ void print128(BT_OCTET16 x, const UINT8 *key_name)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (SMP_CRYPTO_MBEDTLS == FALSE)
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
static void padding ( BT_OCTET16 dest, UINT8 length )
|
||||
{
|
||||
UINT8 i, *p = dest;
|
||||
@@ -89,6 +93,7 @@ static void padding ( BT_OCTET16 dest, UINT8 length )
|
||||
p[BT_OCTET16_LEN - i - 1] = ( i == length ) ? 0x80 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function leftshift_onebit
|
||||
@@ -110,6 +115,8 @@ static void leftshift_onebit(UINT8 *input, UINT8 *output)
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function cmac_aes_cleanup
|
||||
@@ -119,6 +126,7 @@ static void leftshift_onebit(UINT8 *input, UINT8 *output)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
static void cmac_aes_cleanup(void)
|
||||
{
|
||||
if (cmac_cb.text != NULL) {
|
||||
@@ -173,6 +181,7 @@ static BOOLEAN cmac_aes_k_calculate(BT_OCTET16 key, UINT8 *p_signature, UINT16 t
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function cmac_prepare_last_block
|
||||
@@ -203,6 +212,8 @@ static void cmac_prepare_last_block (BT_OCTET16 k1, BT_OCTET16 k2)
|
||||
smp_xor_128(&cmac_cb.text[0], k2);
|
||||
}
|
||||
}
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function cmac_subkey_cont
|
||||
@@ -212,6 +223,7 @@ static void cmac_prepare_last_block (BT_OCTET16 k1, BT_OCTET16 k2)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (SMP_CRYPTO_STACK_NATIVE == TRUE)
|
||||
static void cmac_subkey_cont(tSMP_ENC *p)
|
||||
{
|
||||
UINT8 k1[BT_OCTET16_LEN], k2[BT_OCTET16_LEN];
|
||||
@@ -268,7 +280,7 @@ static BOOLEAN cmac_generate_subkey(BT_OCTET16 key)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* SMP_CRYPTO_MBEDTLS == FALSE */
|
||||
#endif /* SMP_CRYPTO_STACK_NATIVE == TRUE */
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -381,6 +393,82 @@ BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length,
|
||||
/* Clear sensitive data from stack */
|
||||
memset(key_be, 0, sizeof(key_be));
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
#elif (SMP_CRYPTO_TINYCRYPT == TRUE)
|
||||
{
|
||||
/*
|
||||
* TinyCrypt CMAC implementation.
|
||||
* Bluedroid uses little-endian, TinyCrypt uses big-endian.
|
||||
* We reverse the key and input, then reverse the output.
|
||||
*/
|
||||
struct tc_aes_key_sched_struct sched;
|
||||
struct tc_cmac_struct state;
|
||||
UINT8 key_be[BT_OCTET16_LEN];
|
||||
UINT8 *input_be = NULL;
|
||||
UINT8 mac_be[BT_OCTET16_LEN];
|
||||
|
||||
SMP_TRACE_DEBUG("AES128_CMAC (TinyCrypt) 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];
|
||||
}
|
||||
|
||||
/* Setup CMAC */
|
||||
if (tc_cmac_setup(&state, key_be, &sched) == TC_CRYPTO_FAIL) {
|
||||
SMP_TRACE_ERROR("tc_cmac_setup failed");
|
||||
memset(key_be, 0, sizeof(key_be));
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
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");
|
||||
tc_cmac_erase(&state);
|
||||
memset(key_be, 0, sizeof(key_be));
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
return FALSE;
|
||||
}
|
||||
for (UINT16 i = 0; i < length; i++) {
|
||||
input_be[i] = input[length - 1 - i];
|
||||
}
|
||||
|
||||
/* Update CMAC with input data */
|
||||
if (tc_cmac_update(&state, input_be, length) == TC_CRYPTO_FAIL) {
|
||||
SMP_TRACE_ERROR("tc_cmac_update failed");
|
||||
osi_free(input_be);
|
||||
tc_cmac_erase(&state);
|
||||
memset(key_be, 0, sizeof(key_be));
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
return FALSE;
|
||||
}
|
||||
osi_free(input_be);
|
||||
}
|
||||
|
||||
/* Finalize CMAC */
|
||||
if (tc_cmac_final(mac_be, &state) == TC_CRYPTO_FAIL) {
|
||||
SMP_TRACE_ERROR("tc_cmac_final failed");
|
||||
tc_cmac_erase(&state);
|
||||
memset(key_be, 0, sizeof(key_be));
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Convert MAC from big-endian to little-endian and 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];
|
||||
}
|
||||
|
||||
/* Clear sensitive data from stack */
|
||||
tc_cmac_erase(&state);
|
||||
memset(key_be, 0, sizeof(key_be));
|
||||
memset(mac_be, 0, sizeof(mac_be));
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -36,10 +36,16 @@
|
||||
#include "stack/hcimsgs.h"
|
||||
#if (SMP_CRYPTO_MBEDTLS == TRUE)
|
||||
#include "psa/crypto.h"
|
||||
#elif (SMP_CRYPTO_TINYCRYPT == TRUE)
|
||||
#include "tinycrypt/aes.h"
|
||||
#include "tinycrypt/cmac_mode.h"
|
||||
#include "tinycrypt/ecc_dh.h"
|
||||
#include "tinycrypt/ecc.h"
|
||||
#include "tinycrypt/constants.h"
|
||||
#else
|
||||
#include "aes.h"
|
||||
#endif /* SMP_CRYPTO_MBEDTLS */
|
||||
#include "p_256_ecc_pp.h"
|
||||
#endif /* SMP_CRYPTO_MBEDTLS */
|
||||
#include "device/controller.h"
|
||||
|
||||
#ifndef SMP_MAX_ENC_REPEAT
|
||||
@@ -228,6 +234,28 @@ BOOLEAN smp_encrypt_data (UINT8 *key, UINT8 key_len,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#elif (SMP_CRYPTO_TINYCRYPT == TRUE)
|
||||
{
|
||||
struct tc_aes_key_sched_struct sched;
|
||||
|
||||
/* TinyCrypt expects big-endian key and data */
|
||||
if (tc_aes128_set_encrypt_key(&sched, p_rev_key) == TC_CRYPTO_FAIL) {
|
||||
SMP_TRACE_ERROR("%s tc_aes128_set_encrypt_key failed\n", __func__);
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
osi_free(p_start);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (tc_aes_encrypt(p_rev_output, p_rev_data, &sched) == TC_CRYPTO_FAIL) {
|
||||
SMP_TRACE_ERROR("%s tc_aes_encrypt failed\n", __func__);
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
osi_free(p_start);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Clear sensitive data from key schedule */
|
||||
memset(&sched, 0, sizeof(sched));
|
||||
}
|
||||
#else
|
||||
{
|
||||
aes_context ctx;
|
||||
@@ -1214,6 +1242,36 @@ psa_pubkey_cleanup:
|
||||
psa_destroy_key(key_id);
|
||||
/* Clear sensitive data from stack */
|
||||
memset(priv_be, 0, sizeof(priv_be));
|
||||
#elif (SMP_CRYPTO_TINYCRYPT == TRUE)
|
||||
{
|
||||
UINT8 pub_key[64]; /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */
|
||||
UINT8 priv_be[BT_OCTET32_LEN];
|
||||
|
||||
/* 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];
|
||||
}
|
||||
|
||||
/* Compute public key from private key */
|
||||
/* uECC_compute_public_key returns 1 if successful, 0 if failed */
|
||||
if (uECC_compute_public_key(priv_be, pub_key, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) {
|
||||
SMP_TRACE_ERROR("%s uECC_compute_public_key failed\n", __FUNCTION__);
|
||||
memset(priv_be, 0, sizeof(priv_be));
|
||||
memset(pub_key, 0, sizeof(pub_key));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert X and Y from big-endian to little-endian */
|
||||
/* TinyCrypt format: X (32 bytes) || Y (32 bytes) */
|
||||
for (int i = 0; i < BT_OCTET32_LEN; i++) {
|
||||
p_cb->loc_publ_key.x[i] = pub_key[BT_OCTET32_LEN - 1 - i];
|
||||
p_cb->loc_publ_key.y[i] = pub_key[BT_OCTET32_LEN + BT_OCTET32_LEN - 1 - i];
|
||||
}
|
||||
|
||||
/* Clear sensitive data from stack */
|
||||
memset(priv_be, 0, sizeof(priv_be));
|
||||
memset(pub_key, 0, sizeof(pub_key));
|
||||
}
|
||||
#else
|
||||
Point public_key;
|
||||
BT_OCTET32 private_key;
|
||||
@@ -1303,6 +1361,53 @@ psa_dhkey_cleanup:
|
||||
/* Clear sensitive data from stack */
|
||||
memset(priv_be, 0, sizeof(priv_be));
|
||||
memset(shared_secret, 0, sizeof(shared_secret));
|
||||
#elif (SMP_CRYPTO_TINYCRYPT == TRUE)
|
||||
{
|
||||
UINT8 priv_be[BT_OCTET32_LEN];
|
||||
UINT8 peer_pub_be[64]; /* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */
|
||||
UINT8 shared_secret[BT_OCTET32_LEN];
|
||||
|
||||
/* 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];
|
||||
}
|
||||
|
||||
/* Convert peer public key from little-endian to big-endian */
|
||||
/* TinyCrypt format: X (32 bytes) || Y (32 bytes), no prefix */
|
||||
for (int i = 0; i < BT_OCTET32_LEN; i++) {
|
||||
peer_pub_be[i] = p_cb->peer_publ_key.x[BT_OCTET32_LEN - 1 - i];
|
||||
peer_pub_be[BT_OCTET32_LEN + i] = p_cb->peer_publ_key.y[BT_OCTET32_LEN - 1 - i];
|
||||
}
|
||||
|
||||
/* Validate peer public key */
|
||||
/* uECC_valid_public_key returns 0 if valid, negative value if invalid */
|
||||
if (uECC_valid_public_key(peer_pub_be, uECC_secp256r1()) < 0) {
|
||||
SMP_TRACE_ERROR("%s Invalid peer public key\n", __FUNCTION__);
|
||||
memset(priv_be, 0, sizeof(priv_be));
|
||||
memset(peer_pub_be, 0, sizeof(peer_pub_be));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Compute ECDH shared secret */
|
||||
/* uECC_shared_secret returns TC_CRYPTO_SUCCESS (1) if successful, TC_CRYPTO_FAIL (0) if failed */
|
||||
if (uECC_shared_secret(peer_pub_be, priv_be, shared_secret, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) {
|
||||
SMP_TRACE_ERROR("%s uECC_shared_secret failed\n", __FUNCTION__);
|
||||
memset(priv_be, 0, sizeof(priv_be));
|
||||
memset(peer_pub_be, 0, sizeof(peer_pub_be));
|
||||
memset(shared_secret, 0, sizeof(shared_secret));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert shared secret from big-endian to little-endian for DHKey */
|
||||
for (int i = 0; i < BT_OCTET32_LEN; i++) {
|
||||
p_cb->dhkey[i] = shared_secret[BT_OCTET32_LEN - 1 - i];
|
||||
}
|
||||
|
||||
/* Clear sensitive data from stack */
|
||||
memset(priv_be, 0, sizeof(priv_be));
|
||||
memset(peer_pub_be, 0, sizeof(peer_pub_be));
|
||||
memset(shared_secret, 0, sizeof(shared_secret));
|
||||
}
|
||||
#else
|
||||
Point peer_publ_key, new_publ_key;
|
||||
BT_OCTET32 private_key;
|
||||
|
||||
Reference in New Issue
Block a user