mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-28 19:20:54 +00:00
sm: enable check if LTK Request for LE Legacy Pairing comes from Central in LE Device DB, deny if not
This commit is contained in:
parent
caf15bf3c4
commit
6c39055a9f
43
src/ble/sm.c
43
src/ble/sm.c
@ -179,6 +179,7 @@ static uint8_t sm_auth_req = 0;
|
|||||||
static uint8_t sm_io_capabilities = IO_CAPABILITY_NO_INPUT_NO_OUTPUT;
|
static uint8_t sm_io_capabilities = IO_CAPABILITY_NO_INPUT_NO_OUTPUT;
|
||||||
static uint8_t sm_slave_request_security;
|
static uint8_t sm_slave_request_security;
|
||||||
static uint32_t sm_fixed_legacy_pairing_passkey_in_display_role;
|
static uint32_t sm_fixed_legacy_pairing_passkey_in_display_role;
|
||||||
|
static uint8_t sm_reconstruct_ltk_without_le_device_db_entry;
|
||||||
#ifdef ENABLE_LE_SECURE_CONNECTIONS
|
#ifdef ENABLE_LE_SECURE_CONNECTIONS
|
||||||
static uint8_t sm_have_ec_keypair;
|
static uint8_t sm_have_ec_keypair;
|
||||||
#endif
|
#endif
|
||||||
@ -1260,8 +1261,14 @@ static void sm_address_resolution_handle_event(address_resolution_event_t event)
|
|||||||
sm_connection->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED;
|
sm_connection->sm_irk_lookup_state = IRK_LOOKUP_SUCCEEDED;
|
||||||
sm_connection->sm_le_db_index = matched_device_id;
|
sm_connection->sm_le_db_index = matched_device_id;
|
||||||
log_info("ADDRESS_RESOLUTION_SUCEEDED, index %d", sm_connection->sm_le_db_index);
|
log_info("ADDRESS_RESOLUTION_SUCEEDED, index %d", sm_connection->sm_le_db_index);
|
||||||
|
if (sm_connection->sm_role) {
|
||||||
|
// LTK request received before, IRK required -> start LTK calculation
|
||||||
|
if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){
|
||||||
|
sm_connection->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef ENABLE_LE_CENTRAL
|
#ifdef ENABLE_LE_CENTRAL
|
||||||
if (sm_connection->sm_role) break;
|
|
||||||
if (!sm_connection->sm_bonding_requested && !sm_connection->sm_security_request_received) break;
|
if (!sm_connection->sm_bonding_requested && !sm_connection->sm_security_request_received) break;
|
||||||
sm_connection->sm_security_request_received = 0;
|
sm_connection->sm_security_request_received = 0;
|
||||||
sm_connection->sm_bonding_requested = 0;
|
sm_connection->sm_bonding_requested = 0;
|
||||||
@ -1275,8 +1282,14 @@ static void sm_address_resolution_handle_event(address_resolution_event_t event)
|
|||||||
break;
|
break;
|
||||||
case ADDRESS_RESOLUTION_FAILED:
|
case ADDRESS_RESOLUTION_FAILED:
|
||||||
sm_connection->sm_irk_lookup_state = IRK_LOOKUP_FAILED;
|
sm_connection->sm_irk_lookup_state = IRK_LOOKUP_FAILED;
|
||||||
|
if (sm_connection->sm_role) {
|
||||||
|
// LTK request received before, IRK required -> negative LTK reply
|
||||||
|
if (sm_connection->sm_engine_state == SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK){
|
||||||
|
sm_connection->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef ENABLE_LE_CENTRAL
|
#ifdef ENABLE_LE_CENTRAL
|
||||||
if (sm_connection->sm_role) break;
|
|
||||||
if (!sm_connection->sm_bonding_requested && !sm_connection->sm_security_request_received) break;
|
if (!sm_connection->sm_bonding_requested && !sm_connection->sm_security_request_received) break;
|
||||||
sm_connection->sm_security_request_received = 0;
|
sm_connection->sm_security_request_received = 0;
|
||||||
sm_connection->sm_bonding_requested = 0;
|
sm_connection->sm_bonding_requested = 0;
|
||||||
@ -3100,7 +3113,24 @@ static void sm_event_packet_handler (uint8_t packet_type, uint16_t channel, uint
|
|||||||
// For Legacy Pairing (<=> EDIV != 0 || RAND != NULL), we need to recalculated our LTK as a
|
// For Legacy Pairing (<=> EDIV != 0 || RAND != NULL), we need to recalculated our LTK as a
|
||||||
// potentially stored LTK is from the master
|
// potentially stored LTK is from the master
|
||||||
if (sm_conn->sm_local_ediv != 0 || !sm_is_null_random(sm_conn->sm_local_rand)){
|
if (sm_conn->sm_local_ediv != 0 || !sm_is_null_random(sm_conn->sm_local_rand)){
|
||||||
sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST;
|
if (sm_reconstruct_ltk_without_le_device_db_entry){
|
||||||
|
sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// additionally check if remote is in LE Device DB if requested
|
||||||
|
switch(sm_conn->sm_irk_lookup_state){
|
||||||
|
case IRK_LOOKUP_FAILED:
|
||||||
|
log_info("LTK Request: device not in device db");
|
||||||
|
sm_conn->sm_engine_state = SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY;
|
||||||
|
break;
|
||||||
|
case IRK_LOOKUP_SUCCEEDED:
|
||||||
|
sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// wait for irk look doen
|
||||||
|
sm_conn->sm_engine_state = SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3792,7 +3822,8 @@ void sm_init(void){
|
|||||||
sm_min_encryption_key_size = 7;
|
sm_min_encryption_key_size = 7;
|
||||||
|
|
||||||
sm_fixed_legacy_pairing_passkey_in_display_role = 0xffffffff;
|
sm_fixed_legacy_pairing_passkey_in_display_role = 0xffffffff;
|
||||||
|
sm_reconstruct_ltk_without_le_device_db_entry = 1;
|
||||||
|
|
||||||
#ifdef ENABLE_CMAC_ENGINE
|
#ifdef ENABLE_CMAC_ENGINE
|
||||||
sm_cmac_state = CMAC_IDLE;
|
sm_cmac_state = CMAC_IDLE;
|
||||||
#endif
|
#endif
|
||||||
@ -3862,6 +3893,10 @@ void sm_use_fixed_legacy_pairing_passkey_in_display_role(uint32_t passkey){
|
|||||||
sm_fixed_legacy_pairing_passkey_in_display_role = passkey;
|
sm_fixed_legacy_pairing_passkey_in_display_role = passkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow){
|
||||||
|
sm_reconstruct_ltk_without_le_device_db_entry = allow;
|
||||||
|
}
|
||||||
|
|
||||||
static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){
|
static sm_connection_t * sm_get_connection_for_handle(hci_con_handle_t con_handle){
|
||||||
hci_connection_t * hci_con = hci_connection_for_handle(con_handle);
|
hci_connection_t * hci_con = hci_connection_for_handle(con_handle);
|
||||||
if (!hci_con) return NULL;
|
if (!hci_con) return NULL;
|
||||||
|
10
src/ble/sm.h
10
src/ble/sm.h
@ -298,6 +298,16 @@ void sm_use_fixed_ec_keypair(uint8_t * qx, uint8_t * qy, uint8_t * d);
|
|||||||
*/
|
*/
|
||||||
void sm_use_fixed_legacy_pairing_passkey_in_display_role(uint32_t passkey);
|
void sm_use_fixed_legacy_pairing_passkey_in_display_role(uint32_t passkey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allow connection re-encryption in Peripheral (Responder) role for LE Legacy Pairing
|
||||||
|
* without entry for Central device stored in LE Device DB
|
||||||
|
* @note BTstack in Peripheral Role (Responder) supports LE Legacy Pairing without a persistent LE Device DB as
|
||||||
|
* the LTK is reconstructed from a local secret IRK and EDIV + Random stored on Central (Initiator) device
|
||||||
|
* On the downside, it's not really possible to delete a pairing if this is enabled.
|
||||||
|
* @param allow encryption using reconstructed LTK without stored entry (Default: 1)
|
||||||
|
*/
|
||||||
|
void sm_allow_ltk_reconstruction_without_le_device_db_entry(int allow);
|
||||||
|
|
||||||
/* API_END */
|
/* API_END */
|
||||||
|
|
||||||
// PTS testing
|
// PTS testing
|
||||||
|
@ -303,6 +303,7 @@ typedef enum {
|
|||||||
SM_RESPONDER_IDLE,
|
SM_RESPONDER_IDLE,
|
||||||
SM_RESPONDER_SEND_SECURITY_REQUEST,
|
SM_RESPONDER_SEND_SECURITY_REQUEST,
|
||||||
SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST,
|
SM_RESPONDER_PH0_RECEIVED_LTK_REQUEST,
|
||||||
|
SM_RESPONDER_PH0_RECEIVED_LTK_W4_IRK,
|
||||||
SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY,
|
SM_RESPONDER_PH0_SEND_LTK_REQUESTED_NEGATIVE_REPLY,
|
||||||
SM_RESPONDER_PH1_W4_PAIRING_REQUEST,
|
SM_RESPONDER_PH1_W4_PAIRING_REQUEST,
|
||||||
SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED,
|
SM_RESPONDER_PH1_PAIRING_REQUEST_RECEIVED,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user