mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(ble/bluedroid): fix L2CAP, SMP and HCI command issues
- Fix active_count check in l2cu_ble_plcb_active_count - Restore previous state if connection command fails - Fix HCI cmd buffer size off-by-one errors - Fix connect handle length errors - Fix channel sounding event status handling - Fix SMP param_len check in smp_rand_back - Fix spelling: BROCASTER to BROADCASTER in definitions
This commit is contained in:
@@ -177,9 +177,16 @@ static void ECC_NAF(uint8_t *naf, uint32_t *NumNAF, DWORD *k, uint32_t keyLength
|
||||
k[0] = k[0] + 1;
|
||||
if (k[0] == 0) { //overflow
|
||||
j = 1;
|
||||
do {
|
||||
while (j < keyLength && k[j] == 0xFFFFFFFF) {
|
||||
k[j] = 0;
|
||||
j++;
|
||||
}
|
||||
if (j < keyLength) {
|
||||
k[j]++;
|
||||
} while (k[j++] == 0); //overflow
|
||||
}
|
||||
// If j >= keyLength, the entire key is 0xFFFFFFFF,
|
||||
// which should not happen for a valid private key.
|
||||
// In this case, we stop the propagation to prevent buffer overflow.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -621,10 +621,10 @@ void smp_concatenate_peer( tSMP_CB *p_cb, UINT8 **p_data, UINT8 op_code)
|
||||
** Description Generate Confirm/Compare Step1:
|
||||
** p1 = press || preq || rat' || iat'
|
||||
**
|
||||
** Returns void
|
||||
** Returns BOOLEAN
|
||||
**
|
||||
*******************************************************************************/
|
||||
void smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
|
||||
BOOLEAN smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
|
||||
{
|
||||
UINT8 *p = (UINT8 *)p1;
|
||||
tBLE_ADDR_TYPE addr_type = 0;
|
||||
@@ -634,7 +634,7 @@ void smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
|
||||
|
||||
if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, remote_bda, &addr_type)) {
|
||||
SMP_TRACE_ERROR("can not generate confirm for unknown device\n");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BTM_ReadConnectionAddr( p_cb->pairing_bda, p_cb->local_bda, &p_cb->addr_type);
|
||||
@@ -662,6 +662,7 @@ void smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
|
||||
SMP_TRACE_DEBUG("p1 = press || preq || rat' || iat'\n");
|
||||
smp_debug_print_nbyte_little_endian ((UINT8 *)p1, (const UINT8 *)"P1", 16);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -725,7 +726,11 @@ void smp_calculate_comfirm (tSMP_CB *p_cb, BT_OCTET16 rand, BD_ADDR bda)
|
||||
|
||||
SMP_TRACE_DEBUG ("smp_calculate_comfirm \n");
|
||||
/* generate p1 = press || preq || rat' || iat' */
|
||||
smp_gen_p1_4_confirm(p_cb, p1);
|
||||
if (!smp_gen_p1_4_confirm(p_cb, p1)) {
|
||||
|
||||
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
|
||||
return ;
|
||||
}
|
||||
|
||||
/* p1 = rand XOR p1 */
|
||||
smp_xor_128(p1, rand);
|
||||
@@ -1138,6 +1143,12 @@ void smp_continue_private_key_creation (tSMP_CB *p_cb, tBTM_RAND_ENC *p)
|
||||
UINT8 state = p_cb->rand_enc_proc_state & ~0x80;
|
||||
SMP_TRACE_DEBUG ("%s state=0x%x\n", __func__, state);
|
||||
|
||||
/* Validate param_len to prevent buffer overflow/underflow */
|
||||
if (p == NULL || p->param_len != BT_OCTET8_LEN) {
|
||||
SMP_TRACE_ERROR("invalid param_len: %d, expected %d\n", p ? p->param_len : 0, BT_OCTET8_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case SMP_GENERATE_PRIVATE_KEY_0_7:
|
||||
memcpy((void *)p_cb->private_key, p->param_buf, p->param_len);
|
||||
@@ -1543,6 +1554,9 @@ void smp_calculate_peer_commitment(tSMP_CB *p_cb, BT_OCTET16 output_buf)
|
||||
**
|
||||
** Note The LSB is the first octet, the MSB is the last octet of
|
||||
** the AES-CMAC input/output stream.
|
||||
** In little-endian implementation, the message is constructed
|
||||
** as Z||V||U (reversed parameter order) to compensate for
|
||||
** byte order differences with the big-endian specification.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void smp_calculate_f4(UINT8 *u, UINT8 *v, UINT8 *x, UINT8 z, UINT8 *c)
|
||||
@@ -2041,11 +2055,16 @@ BOOLEAN smp_calculate_f5_key(UINT8 *w, UINT8 *t)
|
||||
*******************************************************************************/
|
||||
void smp_calculate_local_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
||||
{
|
||||
UINT8 iocap[3], a[7], b[7];
|
||||
UINT8 iocap[3], a[7] = {0}, b[7] = {0};
|
||||
|
||||
SMP_TRACE_DEBUG ("%s", __FUNCTION__);
|
||||
|
||||
smp_calculate_f5_mackey_and_long_term_key(p_cb);
|
||||
if (!smp_calculate_f5_mackey_and_long_term_key(p_cb)) {
|
||||
UINT8 reason = SMP_PAIR_FAIL_UNKNOWN;
|
||||
p_cb->failure = reason;
|
||||
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
|
||||
return;
|
||||
}
|
||||
|
||||
smp_collect_local_io_capabilities(iocap, p_cb);
|
||||
|
||||
@@ -2068,7 +2087,7 @@ void smp_calculate_local_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
||||
*******************************************************************************/
|
||||
void smp_calculate_peer_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
||||
{
|
||||
UINT8 iocap[3], a[7], b[7];
|
||||
UINT8 iocap[3], a[7] = {0}, b[7] = {0};
|
||||
BT_OCTET16 param_buf;
|
||||
BOOLEAN ret;
|
||||
tSMP_KEY key;
|
||||
@@ -2482,37 +2501,62 @@ static void smp_rand_back(tBTM_RAND_ENC *p)
|
||||
UINT8 *pp = NULL;
|
||||
UINT8 failure = SMP_PAIR_FAIL_UNKNOWN;
|
||||
UINT8 state = p_cb->rand_enc_proc_state & ~0x80;
|
||||
BOOLEAN check_failed = FALSE;
|
||||
|
||||
SMP_TRACE_DEBUG ("%s state=0x%x", __FUNCTION__, state);
|
||||
if (p && p->status == HCI_SUCCESS) {
|
||||
switch (state) {
|
||||
case SMP_GEN_SRAND_MRAND:
|
||||
if (p->param_len != BT_OCTET8_LEN) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
memcpy((void *)p_cb->rand, p->param_buf, p->param_len);
|
||||
smp_generate_rand_cont(p_cb, NULL);
|
||||
break;
|
||||
|
||||
case SMP_GEN_SRAND_MRAND_CONT:
|
||||
if (p->param_len != BT_OCTET8_LEN) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
memcpy((void *)&p_cb->rand[8], p->param_buf, p->param_len);
|
||||
smp_generate_confirm(p_cb, NULL);
|
||||
break;
|
||||
|
||||
case SMP_GEN_DIV_LTK:
|
||||
if (p->param_len < 2) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
pp = p->param_buf;
|
||||
STREAM_TO_UINT16(p_cb->div, pp);
|
||||
smp_generate_ltk_cont(p_cb, NULL);
|
||||
break;
|
||||
|
||||
case SMP_GEN_DIV_CSRK:
|
||||
if (p->param_len < 2) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
pp = p->param_buf;
|
||||
STREAM_TO_UINT16(p_cb->div, pp);
|
||||
smp_compute_csrk(p_cb, NULL);
|
||||
break;
|
||||
|
||||
case SMP_GEN_TK:
|
||||
if (p->param_len < 4) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
smp_proc_passkey(p_cb, p);
|
||||
break;
|
||||
|
||||
case SMP_GEN_RAND_V:
|
||||
if (p->param_len != BT_OCTET8_LEN) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
memcpy(p_cb->enc_rand, p->param_buf, BT_OCTET8_LEN);
|
||||
smp_generate_y(p_cb, NULL);
|
||||
break;
|
||||
@@ -2521,21 +2565,34 @@ static void smp_rand_back(tBTM_RAND_ENC *p)
|
||||
case SMP_GENERATE_PRIVATE_KEY_8_15:
|
||||
case SMP_GENERATE_PRIVATE_KEY_16_23:
|
||||
case SMP_GENERATE_PRIVATE_KEY_24_31:
|
||||
if (p->param_len != BT_OCTET8_LEN) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
smp_continue_private_key_creation(p_cb, p);
|
||||
break;
|
||||
|
||||
case SMP_GEN_NONCE_0_7:
|
||||
if (p->param_len != BT_OCTET8_LEN) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
memcpy((void *)p_cb->rand, p->param_buf, p->param_len);
|
||||
smp_finish_nonce_generation(p_cb);
|
||||
break;
|
||||
|
||||
case SMP_GEN_NONCE_8_15:
|
||||
if (p->param_len != BT_OCTET8_LEN) {
|
||||
check_failed = TRUE;
|
||||
break;
|
||||
}
|
||||
memcpy((void *)&p_cb->rand[8], p->param_buf, p->param_len);
|
||||
smp_process_new_nonce(p_cb);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
if (!check_failed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SMP_TRACE_ERROR("%s key generation failed: (%d)", __FUNCTION__, p_cb->rand_enc_proc_state);
|
||||
|
||||
@@ -749,11 +749,14 @@ static BT_HDR *smp_build_pairing_commitment_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
|
||||
UINT8 *p;
|
||||
UNUSED(cmd_code);
|
||||
|
||||
SMP_TRACE_EVENT("%s\n", __func__);
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + SMP_PAIR_COMMITM_SIZE + L2CAP_MIN_OFFSET))
|
||||
!= NULL) {
|
||||
p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
|
||||
|
||||
/* The transmitter sends 0x03 universally.
|
||||
The receiver performs automatic conversion according to its capabilities to ensure backward compatibility.
|
||||
The state machine operates using the translated opcode. please refer to smp_data_received() in smp_l2c.c
|
||||
Please note that using SMP OPCODE to CONFIRM is not an error.
|
||||
*/
|
||||
UINT8_TO_STREAM (p, SMP_OPCODE_CONFIRM);
|
||||
ARRAY_TO_STREAM (p, p_cb->commitment, BT_OCTET16_LEN);
|
||||
|
||||
@@ -1462,7 +1465,7 @@ void smp_collect_peer_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
|
||||
void smp_collect_local_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
|
||||
{
|
||||
tBLE_ADDR_TYPE addr_type = 0;
|
||||
BD_ADDR bda;
|
||||
BD_ADDR bda = {0};
|
||||
UINT8 *p = le_addr;
|
||||
|
||||
SMP_TRACE_DEBUG("%s\n", __func__);
|
||||
@@ -1485,7 +1488,7 @@ void smp_collect_local_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
|
||||
void smp_collect_peer_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
|
||||
{
|
||||
tBLE_ADDR_TYPE addr_type = 0;
|
||||
BD_ADDR bda;
|
||||
BD_ADDR bda = {0};
|
||||
UINT8 *p = le_addr;
|
||||
|
||||
SMP_TRACE_DEBUG("%s\n", __func__);
|
||||
@@ -1574,8 +1577,8 @@ void smp_save_secure_connections_long_term_key(tSMP_CB *p_cb)
|
||||
*******************************************************************************/
|
||||
BOOLEAN smp_calculate_f5_mackey_and_long_term_key(tSMP_CB *p_cb)
|
||||
{
|
||||
UINT8 a[7];
|
||||
UINT8 b[7];
|
||||
UINT8 a[7] = {0};
|
||||
UINT8 b[7] = {0};
|
||||
UINT8 *p_na;
|
||||
UINT8 *p_nb;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user