OSDN Git Service

DO NOT MERGE Drop Bluetooth connection with weak encryption key
authorJakub Pawlowski <jpawlowski@google.com>
Thu, 14 Feb 2019 11:44:06 +0000 (12:44 +0100)
committerGreg Wroblewski <musashi@google.com>
Tue, 30 Apr 2019 19:53:23 +0000 (12:53 -0700)
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
(cherry picked from commit 027532b3678e3d50ed41270d747df5eb06bc6a8d)

device/src/controller.c
stack/btu/btu_hcif.c
stack/hcic/hcicmds.c
stack/include/btm_ble_api.h
stack/include/hcimsgs.h

index 4440ea5..23799d8 100644 (file)
@@ -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);
 }
index ade7a9b..35bb8e2 100644 (file)
@@ -28,6 +28,7 @@
 #define LOG_TAG "bt_btu_hcif"
 
 #include <assert.h>
+#include <log/log.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -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)
index 34fce49..56196ee 100644 (file)
@@ -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);
index 412fa8e..0cc2e18 100644 (file)
@@ -1304,7 +1304,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);
 
 /*******************************************************************************
 **
index b59cbfa..30d861f 100644 (file)
@@ -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 */