diff options
author | alk3pInjection <webmaster@raspii.tech> | 2024-09-27 15:12:48 +0800 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2024-09-27 15:12:48 +0800 |
commit | 3409a9be62f90b9dbc0dcda0b920c4c1e4caebd4 (patch) | |
tree | 46ade1d3478a7da6230f1852064bf3621de96c31 | |
parent | d0e42ff33dcbd5574ff889c76f74cb8cb320ba26 (diff) | |
parent | e51b31c8b047aa3ae34c4a050bb14049d394169f (diff) |
Merge tag 'LA.QSSI.14.0.r1-17300-qssi.0' into uminekoumineko
"LA.QSSI.14.0.r1-17300-qssi.0"
Change-Id: If91e29e65fffca8c2e78cf46f0adcc1c90361c86
-rw-r--r-- | system/btif/src/btif_storage.cc | 30 | ||||
-rw-r--r-- | system/include/hardware/bluetooth.h | 14 | ||||
-rw-r--r-- | system/stack/btm/btm_sec.cc | 120 | ||||
-rw-r--r-- | system/stack/btm/btm_sec.h | 23 | ||||
-rw-r--r-- | system/stack/btu/btu_hcif.cc | 14 | ||||
-rw-r--r-- | system/stack/include/sec_hci_link_interface.h | 3 | ||||
-rw-r--r-- | system/test/headless/bt_property.cc | 6 | ||||
-rw-r--r-- | system/test/mock/mock_stack_btm_sec.cc | 9 |
8 files changed, 219 insertions, 0 deletions
diff --git a/system/btif/src/btif_storage.cc b/system/btif/src/btif_storage.cc index 4fd1fdaf55..682ac838ef 100644 --- a/system/btif/src/btif_storage.cc +++ b/system/btif/src/btif_storage.cc @@ -85,6 +85,7 @@ using bluetooth::Uuid; #define BTIF_STORAGE_KEY_ADAPTER_NAME "Name" #define BTIF_STORAGE_KEY_ADAPTER_SCANMODE "ScanMode" #define BTIF_STORAGE_KEY_LOCAL_IO_CAPS "LocalIOCaps" +#define BTIF_STORAGE_KEY_MAX_SESSION_KEY_SIZE "MaxSessionKeySize" #define BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT "DiscoveryTimeout" #define BTIF_STORAGE_KEY_GATT_CLIENT_SUPPORTED "GattClientSupportedFeatures" #define BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH "GattClientDatabaseHash" @@ -94,6 +95,8 @@ using bluetooth::Uuid; #define BTIF_STORAGE_PATH_VENDOR_ID "VendorId" #define BTIF_STORAGE_PATH_PRODUCT_ID "ProductId" #define BTIF_STORAGE_PATH_VERSION "ProductVersion" +#define BTIF_STORAGE_KEY_SECURE_CONNECTIONS_SUPPORTED \ + "SecureConnectionsSupported" /* This is a local property to add a device found */ #define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF @@ -223,6 +226,14 @@ static int prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) { info->product_id); btif_config_set_int(bdstr, BTIF_STORAGE_PATH_VERSION, info->version); } break; + case BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED: + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_SECURE_CONNECTIONS_SUPPORTED, + *(uint8_t*)prop->val); + break; + case BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE: + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_MAX_SESSION_KEY_SIZE, + *(uint8_t*)prop->val); + break; case BT_PROPERTY_REMOTE_MODEL_NUM: { strncpy(value, (char*)prop->val, prop->len); value[prop->len] = '\0'; @@ -385,6 +396,25 @@ static int cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) { ret = false; } } break; + case BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED: { + int val; + + if (prop->len >= (int)sizeof(uint8_t)) { + ret = btif_config_get_int( + bdstr, BTIF_STORAGE_KEY_SECURE_CONNECTIONS_SUPPORTED, &val); + *(uint8_t*)prop->val = (uint8_t)val; + } + } break; + + case BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE: { + int val; + + if (prop->len >= (int)sizeof(uint8_t)) { + ret = btif_config_get_int(bdstr, BTIF_STORAGE_KEY_MAX_SESSION_KEY_SIZE, + &val); + *(uint8_t*)prop->val = (uint8_t)val; + } + } break; default: BTIF_TRACE_ERROR("Unknow prop type:%d", prop->type); diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h index 62526cedf3..d2cfbbb0ad 100644 --- a/system/include/hardware/bluetooth.h +++ b/system/include/hardware/bluetooth.h @@ -403,6 +403,20 @@ typedef enum { */ BT_PROPERTY_ENC_KEY_MATERIAL, + /** + * Description - Whether remote device supports Secure Connections mode + * Access mode - GET and SET. + * Data Type - uint8_t. + */ + BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED, + + /** + * Description - Maximum observed session key for remote device + * Access mode - GET and SET. + * Data Type - uint8_t. + */ + BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE, + BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF, } bt_property_type_t; diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc index 9a363568f9..220c32f154 100644 --- a/system/stack/btm/btm_sec.cc +++ b/system/stack/btm/btm_sec.cc @@ -232,6 +232,109 @@ static bool btm_dev_16_digit_authenticated(tBTM_SEC_DEV_REC* p_dev_rec) { /******************************************************************************* * + * Function btm_sec_is_device_sc_downgrade + * + * Description Check for a stored device record matching the candidate + * device, and return true if the stored device has reported + * that it supports Secure Connections mode and the candidate + * device reports that it does not. Otherwise, return false. + * + * Returns bool + * + ******************************************************************************/ +static bool btm_sec_is_device_sc_downgrade(uint16_t hci_handle, + bool secure_connections_supported) { + if (secure_connections_supported) return false; + + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); + if (p_dev_rec == nullptr) return false; + + uint8_t property_val = 0; + bt_property_t property = { + .type = BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED, + .len = sizeof(uint8_t), + .val = &property_val}; + + bt_status_t cached = + btif_storage_get_remote_device_property(&p_dev_rec->bd_addr, &property); + + if (cached == BT_STATUS_FAIL) return false; + + return (bool)property_val; +} + +/******************************************************************************* + * + * Function btm_sec_store_device_sc_support + * + * Description Save Secure Connections support for this device to file + * + ******************************************************************************/ + +static void btm_sec_store_device_sc_support(uint16_t hci_handle, + bool secure_connections_supported) { + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); + if (p_dev_rec == nullptr) return; + + uint8_t property_val = (uint8_t)secure_connections_supported; + bt_property_t property = { + .type = BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED, + .len = sizeof(uint8_t), + .val = &property_val}; + + btif_storage_set_remote_device_property(&p_dev_rec->bd_addr, &property); +} + +/******************************************************************************* + * + * Function btm_sec_is_session_key_size_downgrade + * + * Description Check if there is a stored device record matching this + * handle, and return true if the stored record has a lower + * session key size than the candidate device. + * + * Returns bool + * + ******************************************************************************/ +bool btm_sec_is_session_key_size_downgrade(uint16_t hci_handle, + uint8_t key_size) { + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); + if (p_dev_rec == nullptr) return false; + + uint8_t property_val = 0; + bt_property_t property = {.type = BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE, + .len = sizeof(uint8_t), + .val = &property_val}; + + bt_status_t cached = + btif_storage_get_remote_device_property(&p_dev_rec->bd_addr, &property); + + if (cached == BT_STATUS_FAIL) return false; + + return property_val > key_size; +} + +/******************************************************************************* + * + * Function btm_sec_update_session_key_size + * + * Description Store the max session key size to disk, if possible. + * + ******************************************************************************/ +void btm_sec_update_session_key_size(uint16_t hci_handle, uint8_t key_size) { + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); + if (p_dev_rec == nullptr) return; + + uint8_t property_val = key_size; + bt_property_t property = {.type = BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE, + .len = sizeof(uint8_t), + .val = &property_val}; + + btif_storage_set_remote_device_property(&p_dev_rec->bd_addr, &property); +} + +/******************************************************************************* + * * Function access_secure_service_from_temp_bond * * Description a utility function to test whether an access to @@ -4065,6 +4168,13 @@ void btm_sec_link_key_notification(const RawAddress& p_bda, } } + if (p_dev_rec->is_bond_type_persistent() && + (p_dev_rec->is_device_type_br_edr() || + p_dev_rec->is_device_type_dual_mode())) { + btm_sec_store_device_sc_support(p_dev_rec->get_br_edr_hci_handle(), + p_dev_rec->SupportsSecureConnections()); + } + /* If name is not known at this point delay calling callback until the name is */ /* resolved. Unless it is a HID Device and we really need to send all link @@ -5144,6 +5254,16 @@ void btm_sec_set_peer_sec_caps(uint16_t hci_handle, bool ssp_supported, tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); if (p_dev_rec == nullptr) return; + // Drop the connection here if the remote attempts to downgrade from Secure + // Connections mode. + if (btm_sec_is_device_sc_downgrade(hci_handle, sc_supported)) { + acl_set_disconnect_reason(HCI_ERR_HOST_REJECT_SECURITY); + btm_sec_send_hci_disconnect( + p_dev_rec, HCI_ERR_AUTH_FAILURE, hci_handle, + "attempted to downgrade from Secure Connections mode"); + return; + } + p_dev_rec->remote_feature_received = true; p_dev_rec->remote_supports_hci_role_switch = hci_role_switch_supported; diff --git a/system/stack/btm/btm_sec.h b/system/stack/btm/btm_sec.h index 2647f0764d..6596f6fd15 100644 --- a/system/stack/btm/btm_sec.h +++ b/system/stack/btm/btm_sec.h @@ -789,5 +789,28 @@ void btm_sec_set_peer_sec_caps(uint16_t hci_handle, bool ssp_supported, void btm_sec_cr_loc_oob_data_cback_event(const RawAddress& address, tSMP_LOC_OOB_DATA loc_oob_data); +/******************************************************************************* + * + * Function btm_sec_is_session_key_size_downgrade + * + * Description Check if there is a stored device record matching this + * handle, and return true if the stored record has a lower + * session key size than the candidate device. + * + * Returns bool + * + ******************************************************************************/ +bool btm_sec_is_session_key_size_downgrade(uint16_t hci_handle, + uint8_t key_size); + +/******************************************************************************* + * + * Function btm_sec_update_session_key_size + * + * Description Store the max session key size to disk, if possible. + * + ******************************************************************************/ +void btm_sec_update_session_key_size(uint16_t hci_handle, uint8_t key_size); + // Return DEV_CLASS (uint8_t[3]) of bda. If record doesn't exist, create one. const uint8_t* btm_get_dev_class(const RawAddress& bda); diff --git a/system/stack/btu/btu_hcif.cc b/system/stack/btu/btu_hcif.cc index 605e95e15d..c71534499d 100644 --- a/system/stack/btu/btu_hcif.cc +++ b/system/stack/btu/btu_hcif.cc @@ -918,6 +918,20 @@ static void read_encryption_key_size_complete_after_encryption_change(uint8_t st return; } + if (btm_sec_is_session_key_size_downgrade(handle, key_size)) { + LOG_ERROR( + "encryption key size lower than cached value, disconnecting. " + "handle: 0x%x attempted key size: %d", + handle, key_size); + acl_disconnect_from_handle( + handle, HCI_ERR_HOST_REJECT_SECURITY, + "stack::btu::btu_hcif::read_encryption_key_size_complete_after_" + "encryption_change Key Size Downgrade"); + return; + } + + btm_sec_update_session_key_size(handle, key_size); + // good key size - succeed btm_acl_encrypt_change(handle, static_cast<tHCI_STATUS>(status), 1 /* enable */); diff --git a/system/stack/include/sec_hci_link_interface.h b/system/stack/include/sec_hci_link_interface.h index dce3c479fd..1fecde74ed 100644 --- a/system/stack/include/sec_hci_link_interface.h +++ b/system/stack/include/sec_hci_link_interface.h @@ -37,6 +37,8 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status); void btm_sec_disconnected(uint16_t handle, tHCI_STATUS reason, std::string); void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable); +bool btm_sec_is_session_key_size_downgrade(uint16_t hci_handle, + uint8_t key_size); void btm_sec_link_key_notification(const RawAddress& p_bda, const Octet16& link_key, uint8_t key_type); void btm_sec_link_key_request(const uint8_t* p_event); @@ -46,4 +48,5 @@ void btm_sec_rmt_name_request_complete(const RawAddress* bd_addr, const uint8_t* bd_name, tHCI_STATUS status); void btm_sec_update_clock_offset(uint16_t handle, uint16_t clock_offset); +void btm_sec_update_session_key_size(uint16_t hci_handle, uint8_t key_size); void btm_simple_pair_complete(const uint8_t* p); diff --git a/system/test/headless/bt_property.cc b/system/test/headless/bt_property.cc index 5b6c2d5397..a599e3f53a 100644 --- a/system/test/headless/bt_property.cc +++ b/system/test/headless/bt_property.cc @@ -107,6 +107,12 @@ void process_property(const RawAddress& bd_addr, const bt_property_t* prop) { case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: LOG_CONSOLE("BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER"); break; + case BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED: + LOG_CONSOLE("BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED"); + break; + case BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE: + LOG_CONSOLE("BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE"); + break; default: { LOG_CONSOLE("Unable to find BT property bd_addr:%s type:%d ptr:%p", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), prop->type, prop); diff --git a/system/test/mock/mock_stack_btm_sec.cc b/system/test/mock/mock_stack_btm_sec.cc index d24156e9a0..7819435b89 100644 --- a/system/test/mock/mock_stack_btm_sec.cc +++ b/system/test/mock/mock_stack_btm_sec.cc @@ -116,6 +116,11 @@ bool btm_sec_is_a_bonded_dev(const RawAddress& bda) { inc_func_call_count(__func__); return false; } +bool btm_sec_is_session_key_size_downgrade(uint16_t hci_handle, + uint8_t key_size) { + inc_func_call_count(__func__); + return false; +} bool is_sec_state_equal(void* data, void* context) { inc_func_call_count(__func__); return false; @@ -312,6 +317,10 @@ void btm_sec_set_peer_sec_caps(uint16_t hci_handle, bool ssp_supported, void btm_sec_update_clock_offset(uint16_t handle, uint16_t clock_offset) { inc_func_call_count(__func__); } +void btm_sec_update_session_key_size(uint16_t hci_handle, uint8_t key_size) { + inc_func_call_count(__func__); +} + void btm_simple_pair_complete(const uint8_t* p) { inc_func_call_count(__func__); } |