Merge cherrypicks of [7077329, 7077440, 7077330, 7077468, 7076852, 7077469, 7077580, 7077581, 7077582, 7074025, 7077706, 7077707, 7077708, 7077388, 7077583, 7077584, 7077585, 7077726, 7077727, 7077331, 7077332, 7077459, 7077709, 7077710, 7077711, 7077712, 7077460, 7077461, 7077333, 7077334, 7077696] into pi-qpr3-release

Change-Id: I2136d4f180dc2e9efb6030ea13539c51fb1adc61
diff --git a/btif/Android.bp b/btif/Android.bp
index 4b2dc30..0bbc241 100644
--- a/btif/Android.bp
+++ b/btif/Android.bp
@@ -127,6 +127,7 @@
         "libprotobuf-cpp-lite",
         "libcutils",
         "libutils",
+        "libstatslog",
     ],
     static_libs: [
         "libbt-bta",
diff --git a/btif/src/btif_storage.cc b/btif/src/btif_storage.cc
index f64875e..ef2e191 100644
--- a/btif/src/btif_storage.cc
+++ b/btif/src/btif_storage.cc
@@ -35,6 +35,7 @@
 #include <alloca.h>
 #include <base/logging.h>
 #include <ctype.h>
+#include <log/log.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
@@ -794,6 +795,45 @@
   return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
+/* Some devices hardcode sample LTK value from spec, instead of generating one.
+ * Treat such devices as insecure, and remove such bonds when bluetooth
+ * restarts. Removing them after disconnection is handled separately.
+ *
+ * We still allow such devices to bond in order to give the user a chance to
+ * update firmware.
+ */
+static void remove_devices_with_sample_ltk() {
+  std::vector<RawAddress> bad_ltk;
+  for (const section_t& section : btif_config_sections()) {
+    const std::string& name = section.name;
+    if (!RawAddress::IsValidAddress(name)) {
+      continue;
+    }
+
+    RawAddress bd_addr;
+    RawAddress::FromString(name, bd_addr);
+
+    tBTA_LE_KEY_VALUE key;
+    memset(&key, 0, sizeof(key));
+
+    if (btif_storage_get_ble_bonding_key(
+            &bd_addr, BTIF_DM_LE_KEY_PENC, (uint8_t*)&key,
+            sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) {
+      if (is_sample_ltk(key.penc_key.ltk)) {
+        bad_ltk.push_back(bd_addr);
+      }
+    }
+  }
+
+  for (RawAddress address : bad_ltk) {
+    android_errorWriteLog(0x534e4554, "128437297");
+    LOG(ERROR) << __func__
+               << ": removing bond to device using test TLK: " << address;
+
+    btif_storage_remove_bonded_device(&address);
+  }
+}
+
 /*******************************************************************************
  *
  * Function         btif_storage_load_bonded_devices
@@ -821,6 +861,8 @@
   Uuid remote_uuids[BT_MAX_NUM_UUIDS];
   bt_status_t status;
 
+  remove_devices_with_sample_ltk();
+
   btif_in_fetch_bonded_devices(&bonded_devices, 1);
 
   /* Now send the adapter_properties_cb with all adapter_properties */
diff --git a/device/src/controller.cc b/device/src/controller.cc
index a07e54b..02a3998 100644
--- a/device/src/controller.cc
+++ b/device/src/controller.cc
@@ -264,6 +264,10 @@
         response, &number_of_local_supported_codecs, local_supported_codecs);
   }
 
+  if (!HCI_READ_ENCR_KEY_SIZE_SUPPORTED(supported_commands)) {
+    LOG(FATAL) << " Controller must support Read Encryption Key Size command";
+  }
+
   readable = true;
   return future_new_immediate(FUTURE_SUCCESS);
 }
diff --git a/main/Android.bp b/main/Android.bp
index c07b849..04d8ca6 100644
--- a/main/Android.bp
+++ b/main/Android.bp
@@ -51,6 +51,7 @@
         "libutils",
         "libtinyxml2",
         "libz",
+        "libstatslog",
     ],
     static_libs: [
         "libbt-sbc-decoder",
diff --git a/stack/Android.bp b/stack/Android.bp
index ceb2f13..03e2c94 100644
--- a/stack/Android.bp
+++ b/stack/Android.bp
@@ -178,6 +178,7 @@
     shared_libs: [
         "libcutils",
         "liblog",
+        "libstatslog",
     ],
     required: [
         "libldacBT_enc",
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index b080901..19280ad 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -24,6 +24,7 @@
 
 #define LOG_TAG "bt_btm_sec"
 
+#include <log/log.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
@@ -48,6 +49,8 @@
 bool(APPL_AUTH_WRITE_EXCEPTION)(const RawAddress& bd_addr);
 #endif
 
+extern void bta_dm_remove_device(const RawAddress& bd_addr);
+
 /*******************************************************************************
  *             L O C A L    F U N C T I O N     P R O T O T Y P E S            *
  ******************************************************************************/
@@ -4530,6 +4533,18 @@
       p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN);
   }
 
+  /* Some devices hardcode sample LTK value from spec, instead of generating
+   * one. Treat such devices as insecure, and remove such bonds on
+   * disconnection.
+   */
+  if (is_sample_ltk(p_dev_rec->ble.keys.pltk)) {
+    android_errorWriteLog(0x534e4554, "128437297");
+    LOG(INFO) << __func__ << " removing bond to device that used sample LTK: "
+              << p_dev_rec->bd_addr;
+
+    bta_dm_remove_device(p_dev_rec->bd_addr);
+  }
+
   BTM_TRACE_EVENT("%s after update sec_flags=0x%x", __func__,
                   p_dev_rec->sec_flags);
 
diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc
index eac71a6..fbd7695 100644
--- a/stack/btu/btu_hcif.cc
+++ b/stack/btu/btu_hcif.cc
@@ -32,6 +32,8 @@
 #include <base/location.h>
 #include <base/logging.h>
 #include <base/threading/thread.h>
+#include <log/log.h>
+#include <statslog.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -719,6 +721,38 @@
   btm_sec_rmt_name_request_complete(&bd_addr, p, status);
 }
 
+constexpr uint8_t MIN_KEY_SIZE = 7;
+
+static void read_encryption_key_size_complete_after_encryption_change(
+    uint8_t status, uint16_t handle, uint8_t key_size) {
+  int ret = android::util::stats_write(
+      android::util::BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED, "", handle,
+      HCI_READ_ENCR_KEY_SIZE, HCI_COMMAND_COMPLETE_EVT, status, 0, key_size);
+  if (ret < 0) {
+    LOG(WARNING) << __func__ << ": failed to log encryption key size "
+                 << std::to_string(key_size);
+  }
+
+  if (status != HCI_SUCCESS) {
+    LOG(INFO) << __func__ << ": disconnecting, status: " << loghex(status);
+    btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
+    return;
+  }
+
+  if (key_size < MIN_KEY_SIZE) {
+    android_errorWriteLog(0x534e4554, "124301137");
+    LOG(ERROR) << __func__
+               << " encryption key too short, disconnecting. handle: "
+               << loghex(handle) << " key_size: " << +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
@@ -737,8 +771,15 @@
   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 {
+    btsnd_hcic_read_encryption_key_size(
+        handle,
+        base::Bind(&read_encryption_key_size_complete_after_encryption_change));
+  }
 }
 
 /*******************************************************************************
@@ -1643,22 +1684,55 @@
  * End of Simple Pairing Events
  **********************************************/
 
-/**********************************************
- * BLE Events
- **********************************************/
+static void read_encryption_key_size_complete_after_key_refresh(
+    uint8_t status, uint16_t handle, uint8_t key_size) {
+  int ret = android::util::stats_write(
+      android::util::BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED, "", handle,
+      HCI_READ_ENCR_KEY_SIZE, HCI_COMMAND_COMPLETE_EVT, status, 0, key_size);
+  if (ret < 0) {
+    LOG(WARNING) << __func__ << ": failed to log encryption key size "
+                 << std::to_string(key_size);
+  }
+
+  if (status != HCI_SUCCESS) {
+    LOG(INFO) << __func__ << ": disconnecting, status: " << loghex(status);
+    btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
+    return;
+  }
+
+  if (key_size < MIN_KEY_SIZE) {
+    android_errorWriteLog(0x534e4554, "124301137");
+    LOG(ERROR) << __func__
+               << " encryption key too short, disconnecting. handle: "
+               << loghex(handle) << " key_size: " << +key_size;
+
+    btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
+    return;
+  }
+
+  btm_sec_encrypt_change(handle, status, 1 /* enc_enable */);
+}
+
 static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p) {
   uint8_t status;
-  uint8_t enc_enable = 0;
   uint16_t handle;
 
   STREAM_TO_UINT8(status, p);
   STREAM_TO_UINT16(handle, 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, (status == HCI_SUCCESS) ? 1 : 0);
+  } else {
+    btsnd_hcic_read_encryption_key_size(
+        handle,
+        base::Bind(&read_encryption_key_size_complete_after_key_refresh));
+  }
 }
 
+/**********************************************
+ * BLE Events
+ **********************************************/
+
 static void btu_ble_ll_conn_complete_evt(uint8_t* p, uint16_t evt_len) {
   btm_ble_conn_complete(p, evt_len, false);
 }
diff --git a/stack/hcic/hcicmds.cc b/stack/hcic/hcicmds.cc
index 56ff381..0778afc 100644
--- a/stack/hcic/hcicmds.cc
+++ b/stack/hcic/hcicmds.cc
@@ -1311,6 +1311,32 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
+static void read_encryption_key_size_complete(
+    ReadEncKeySizeCb cb, uint8_t* return_parameters,
+    uint16_t return_parameters_length) {
+  uint8_t status;
+  uint16_t handle;
+  uint8_t key_size;
+  STREAM_TO_UINT8(status, return_parameters);
+  STREAM_TO_UINT16(handle, return_parameters);
+  STREAM_TO_UINT8(key_size, return_parameters);
+
+  std::move(cb).Run(status, handle, key_size);
+}
+
+void btsnd_hcic_read_encryption_key_size(uint16_t handle, ReadEncKeySizeCb cb) {
+  constexpr uint8_t len = 2;
+  uint8_t param[len];
+  memset(param, 0, len);
+
+  uint8_t* p = param;
+  UINT16_TO_STREAM(p, handle);
+
+  btu_hcif_send_cmd_with_cb(
+      FROM_HERE, HCI_READ_ENCR_KEY_SIZE, param, len,
+      base::Bind(&read_encryption_key_size_complete, base::Passed(&cb)));
+}
+
 void btsnd_hcic_read_failed_contact_counter(uint16_t handle) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
diff --git a/stack/include/bt_types.h b/stack/include/bt_types.h
index 54a2eb2..3c479af 100644
--- a/stack/include/bt_types.h
+++ b/stack/include/bt_types.h
@@ -21,6 +21,7 @@
 
 #include <stdbool.h>
 #include <stdint.h>
+#include <string.h>
 
 #ifndef FALSE
 #define FALSE false
@@ -925,4 +926,12 @@
 /* Define a function for logging */
 typedef void(BT_LOG_FUNC)(int trace_type, const char* fmt_str, ...);
 
+static inline bool is_sample_ltk(const BT_OCTET16 ltk) {
+  /* Sample LTK from BT Spec 5.1 | Vol 6, Part C 1
+   * 0x4C68384139F574D836BCF34E9DFB01BF */
+  const uint8_t SAMPLE_LTK[] = {0xbf, 0x01, 0xfb, 0x9d, 0x4e, 0xf3, 0xbc, 0x36,
+                                0xd8, 0x74, 0xf5, 0x39, 0x41, 0x38, 0x68, 0x4c};
+  return memcmp(ltk, SAMPLE_LTK, BT_OCTET16_LEN) == 0;
+}
+
 #endif
diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h
index f0fb9e6..c8ffa5e 100644
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -366,6 +366,18 @@
 
 /*******************************************************************************
  *
+ * 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);
+
+/*******************************************************************************
+ *
  * Function         BTM_ReadRemoteConnectionAddr
  *
  * Description      Read the remote device address currently used.
diff --git a/stack/include/hcimsgs.h b/stack/include/hcimsgs.h
index a909751..63ea8f4 100644
--- a/stack/include/hcimsgs.h
+++ b/stack/include/hcimsgs.h
@@ -612,6 +612,9 @@
 
 extern void btsnd_hcic_get_link_quality(uint16_t handle); /* Get Link Quality */
 extern void btsnd_hcic_read_rssi(uint16_t handle);        /* Read RSSI */
+using ReadEncKeySizeCb = base::OnceCallback<void(uint8_t, uint16_t, uint8_t)>;
+extern void btsnd_hcic_read_encryption_key_size(uint16_t handle,
+                                                ReadEncKeySizeCb cb);
 extern void btsnd_hcic_read_failed_contact_counter(uint16_t handle);
 extern void btsnd_hcic_read_automatic_flush_timeout(uint16_t handle);
 extern void btsnd_hcic_enable_test_mode(