From 027532b3678e3d50ed41270d747df5eb06bc6a8d Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Thu, 14 Feb 2019 12:44:06 +0100 Subject: [PATCH] DO NOT MERGE Drop Bluetooth connection with weak encryption key This patch requires Bluetooth chip to support HCI Read Encryption Key Size command and will cause Bluetooth to crash if this command is not supported on a device. Such device should not take this patch and should look for alternative solution to drop Bluetooth connection with weak encryption key. Bug: 124301137 Change-Id: Id4b6b4e765628397a79e6806f45c2cd27acebd5b --- device/src/controller.c | 2 ++ stack/btu/btu_hcif.c | 88 +++++++++++++++++++++++++++++++++++++++++++-- stack/hcic/hcicmds.c | 13 +++++++ stack/include/btm_ble_api.h | 12 ++++++- stack/include/hcimsgs.h | 1 + 5 files changed, 112 insertions(+), 4 deletions(-) diff --git a/device/src/controller.c b/device/src/controller.c index 4440ea55a..23799d803 100644 --- a/device/src/controller.c +++ b/device/src/controller.c @@ -252,6 +252,8 @@ static future_t *start_up(void) { &number_of_local_supported_codecs, local_supported_codecs); } + assert(HCI_READ_ENCR_KEY_SIZE_SUPPORTED(supported_commands)); + readable = true; return future_new_immediate(FUTURE_SUCCESS); } diff --git a/stack/btu/btu_hcif.c b/stack/btu/btu_hcif.c index 9fa29e77d..3c09c259c 100644 --- a/stack/btu/btu_hcif.c +++ b/stack/btu/btu_hcif.c @@ -28,6 +28,7 @@ #define LOG_TAG "bt_btu_hcif" #include +#include #include #include #include @@ -601,6 +602,55 @@ static void btu_hcif_rmt_name_request_comp_evt (UINT8 *p, UINT16 evt_len) btm_sec_rmt_name_request_complete (bd_addr, p, status); } +const uint8_t MIN_KEY_SIZE = 7; +bool read_key_send_from_key_refresh = false; + +static void read_encryption_key_size_complete_after_key_refresh( + uint8_t status, uint16_t handle, uint8_t key_size) { + if (status != HCI_SUCCESS) { + HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status); + btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER); + return; + } + + if (key_size < MIN_KEY_SIZE) { + android_errorWriteLog(0x534e4554, "124301137"); + HCI_TRACE_ERROR( + "%s encryption key too short, disconnecting. handle: 0x%02x, key_size: " + "%d", + __func__, handle, key_size); + + btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY); + return; + } + + btm_sec_encrypt_change(handle, status, 1 /* enc_enable */); +} + +static void read_encryption_key_size_complete_after_encryption_change( + uint8_t status, uint16_t handle, uint8_t key_size) { + if (status != HCI_SUCCESS) { + HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status); + btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER); + return; + } + + if (key_size < MIN_KEY_SIZE) { + android_errorWriteLog(0x534e4554, "124301137"); + HCI_TRACE_ERROR( + "%s encryption key too short, disconnecting. handle: 0x%02x, key_size: " + "%d", + __func__, handle, key_size); + + btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY); + return; + } + + // good key size - succeed + btm_acl_encrypt_change(handle, status, 1 /* enable */); + btm_sec_encrypt_change(handle, status, 1 /* enable */); +} + /******************************************************************************* ** ** Function btu_hcif_encryption_change_evt @@ -620,8 +670,14 @@ static void btu_hcif_encryption_change_evt (UINT8 *p) STREAM_TO_UINT16 (handle, p); STREAM_TO_UINT8 (encr_enable, p); - btm_acl_encrypt_change (handle, status, encr_enable); - btm_sec_encrypt_change (handle, status, encr_enable); + if (status != HCI_SUCCESS || encr_enable == 0 || + BTM_IsBleConnection(handle)) { + btm_acl_encrypt_change (handle, status, encr_enable); + btm_sec_encrypt_change (handle, status, encr_enable); + } else { + read_key_send_from_key_refresh = false; + btsnd_hcic_read_encryption_key_size(handle); + } } /******************************************************************************* @@ -824,6 +880,26 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_read_inq_tx_power_complete(p); break; + case HCI_READ_ENCR_KEY_SIZE: { + UINT8 *pp = p; + + UINT8 status; + UINT16 handle; + UINT8 key_size; + + STREAM_TO_UINT8 (status, pp); + STREAM_TO_UINT16 (handle, pp); + STREAM_TO_UINT8 (key_size, pp); + + if (read_key_send_from_key_refresh) { + read_encryption_key_size_complete_after_encryption_change(status, handle, key_size); + } else { + read_encryption_key_size_complete_after_key_refresh(status, handle, key_size); + } + + } + break; + #if (BLE_INCLUDED == TRUE) /* BLE Commands sComplete*/ case HCI_BLE_ADD_WHITE_LIST: @@ -1595,6 +1671,7 @@ static void btu_hcif_enhanced_flush_complete_evt (void) ** BLE Events ***********************************************/ #if (defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE) + static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p) { UINT8 status; @@ -1606,7 +1683,12 @@ static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p) if (status == HCI_SUCCESS) enc_enable = 1; - btm_sec_encrypt_change (handle, status, enc_enable); + if (status != HCI_SUCCESS || BTM_IsBleConnection(handle)) { + btm_sec_encrypt_change (handle, status, enc_enable); + } else { + read_key_send_from_key_refresh = true; + btsnd_hcic_read_encryption_key_size(handle); + } } static void btu_ble_process_adv_pkt (UINT8 *p) diff --git a/stack/hcic/hcicmds.c b/stack/hcic/hcicmds.c index 34fce493d..56196ee71 100644 --- a/stack/hcic/hcicmds.c +++ b/stack/hcic/hcicmds.c @@ -1356,6 +1356,19 @@ BOOLEAN btsnd_hcic_read_rssi (UINT16 handle) return (TRUE); } +BOOLEAN btsnd_hcic_read_encryption_key_size(UINT16 handle) { + BT_HDR *p = (BT_HDR *)osi_malloc(HCI_CMD_BUF_SIZE); + UINT8 *pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + 2; + p->offset = 0; + + UINT16_TO_STREAM (pp, handle); + + btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} + BOOLEAN btsnd_hcic_enable_test_mode (void) { BT_HDR *p = (BT_HDR *)osi_malloc(HCI_CMD_BUF_SIZE); diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h index ab5ea38b1..2777d1bb7 100644 --- a/stack/include/btm_ble_api.h +++ b/stack/include/btm_ble_api.h @@ -1288,7 +1288,17 @@ extern BOOLEAN BTM_BleVerifySignature (BD_ADDR bd_addr, UINT8 *p_orig, extern void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, tBLE_ADDR_TYPE *p_addr_type); - +/******************************************************************************* + * + * Function BTM_IsBleConnection + * + * Description This function is called to check if the connection handle + * for an LE link + * + * Returns true if connection is LE link, otherwise false. + * + ******************************************************************************/ +extern bool BTM_IsBleConnection(uint16_t conn_handle); /******************************************************************************* ** diff --git a/stack/include/hcimsgs.h b/stack/include/hcimsgs.h index b59cbfa5a..30d861fbe 100644 --- a/stack/include/hcimsgs.h +++ b/stack/include/hcimsgs.h @@ -603,6 +603,7 @@ extern BOOLEAN btsnd_hcic_write_cur_iac_lap (UINT8 num_cur_iac, extern BOOLEAN btsnd_hcic_get_link_quality (UINT16 handle); /* Get Link Quality */ extern BOOLEAN btsnd_hcic_read_rssi (UINT16 handle); /* Read RSSI */ +extern BOOLEAN btsnd_hcic_read_encryption_key_size (UINT16 handle); /* Read encryption key size */ extern BOOLEAN btsnd_hcic_enable_test_mode (void); /* Enable Device Under Test Mode */ extern BOOLEAN btsnd_hcic_write_pagescan_type(UINT8 type); /* Write Page Scan Type */ extern BOOLEAN btsnd_hcic_write_inqscan_type(UINT8 type); /* Write Inquiry Scan Type */ -- 2.11.0