Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02d183c3 authored by Myles Watson's avatar Myles Watson Committed by Gerrit Code Review
Browse files

Merge changes Iaf6e7580,I60f9fb2c,If5e5cbd5 into main

* changes:
  Move parsing of btm_sec_rmt_host_support_feat_evt
  btm_sec: Move encryption key checks out of btu
  Security: Move parsing to HCI: SP events
parents f3368822 15e8595f
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -209,16 +209,10 @@ void bluetooth::shim::ACL_RemoteNameRequest(const RawAddress& addr,
      GetGdShimHandler()->BindOnce(
          [](RawAddress addr, uint64_t features) {
            static_assert(sizeof(features) == 8);
            auto addr_array = addr.ToArray();
            auto p = (uint8_t*)osi_malloc(addr_array.size() + sizeof(features));
            std::copy(addr_array.rbegin(), addr_array.rend(), p);
            for (int i = 0; i != sizeof(features); ++i) {
              p[addr_array.size() + i] = features & ((1 << 8) - 1);
              features >>= 8;
            }
            do_in_main_thread(
                FROM_HERE,
                base::BindOnce(btm_sec_rmt_host_support_feat_evt, p));
                base::BindOnce(btm_sec_rmt_host_support_feat_evt, addr,
                               static_cast<uint8_t>(features & 0xff)));
          },
          addr),
      GetGdShimHandler()->BindOnce(
+59 −14
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
#include "stack/include/btm_log_history.h"
#include "stack/include/btm_sec_api.h"
#include "stack/include/btm_status.h"
#include "stack/include/hci_error_code.h"
#include "stack/include/l2cap_security_interface.h"
#include "stack/include/main_thread.h"
#include "stack/include/smp_api.h"
@@ -2559,28 +2560,25 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr,
 * Returns          void
 *
 ******************************************************************************/
void btm_sec_rmt_host_support_feat_evt(const uint8_t* p) {
void btm_sec_rmt_host_support_feat_evt(const RawAddress bd_addr,
                                       uint8_t features_0) {
  tBTM_SEC_DEV_REC* p_dev_rec;
  RawAddress bd_addr; /* peer address */
  BD_FEATURES features;

  STREAM_TO_BDADDR(bd_addr, p);
  p_dev_rec = btm_find_or_alloc_dev(bd_addr);

  LOG_INFO("Got btm_sec_rmt_host_support_feat_evt from %s",
           ADDRESS_TO_LOGGABLE_CSTR(bd_addr));

  LOG_VERBOSE("btm_sec_rmt_host_support_feat_evt  sm4: 0x%x  p[0]: 0x%x",
              p_dev_rec->sm4, p[0]);
              p_dev_rec->sm4, features_0);

  if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4)) {
    p_dev_rec->sm4 = BTM_SM4_KNOWN;
    STREAM_TO_ARRAY(features, p, HCI_FEATURE_BYTES_PER_PAGE);
    if (HCI_SSP_HOST_SUPPORTED(features)) {
    if (HCI_SSP_HOST_SUPPORTED((std::array<uint8_t, 1>({features_0})))) {
      p_dev_rec->sm4 = BTM_SM4_TRUE;
    }
    LOG_VERBOSE("btm_sec_rmt_host_support_feat_evt sm4: 0x%x features[0]: 0x%x",
                p_dev_rec->sm4, features[0]);
                p_dev_rec->sm4, features_0);
  }
}

@@ -2833,15 +2831,14 @@ void btm_io_capabilities_rsp(const tBTM_SP_IO_RSP evt_data) {
 * Returns          void
 *
 ******************************************************************************/
void btm_proc_sp_req_evt(tBTM_SP_EVT event, const uint8_t* p) {
void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda,
                         const uint32_t value) {
  tBTM_STATUS status = BTM_ERR_PROCESSING;
  tBTM_SP_EVT_DATA evt_data;
  RawAddress& p_bda = evt_data.cfm_req.bd_addr;
  tBTM_SEC_DEV_REC* p_dev_rec;

  /* All events start with bd_addr */
  STREAM_TO_BDADDR(p_bda, p);

  p_bda = bda;
  VLOG(2) << " BDA: " << ADDRESS_TO_LOGGABLE_STR(p_bda) << " event: 0x"
          << std::hex << +event
          << " State: " << btm_pair_state_descr(btm_sec_cb.pairing_state);
@@ -2862,7 +2859,7 @@ void btm_proc_sp_req_evt(tBTM_SP_EVT event, const uint8_t* p) {
        btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM);

        /* The device record must be allocated in the "IO cap exchange" step */
        STREAM_TO_UINT32(evt_data.cfm_req.num_val, p);
        evt_data.cfm_req.num_val = value;
        LOG_VERBOSE("BTM_SP_CFM_REQ_EVT:  num_val: %u",
                    evt_data.cfm_req.num_val);

@@ -2908,7 +2905,7 @@ void btm_proc_sp_req_evt(tBTM_SP_EVT event, const uint8_t* p) {

      case BTM_SP_KEY_NOTIF_EVT:
        /* Passkey notification (other side is a keyboard) */
        STREAM_TO_UINT32(evt_data.key_notif.passkey, p);
        evt_data.key_notif.passkey = value;
        LOG_VERBOSE("BTM_SP_KEY_NOTIF_EVT:  passkey: %u",
                    evt_data.key_notif.passkey);

@@ -3991,6 +3988,54 @@ void btm_sec_role_changed(tHCI_STATUS hci_status, const RawAddress& bd_addr,
  }
}

constexpr uint8_t MIN_KEY_SIZE = 7;

static void read_encryption_key_size_complete_after_key_refresh(
    uint8_t status, uint16_t handle, uint8_t key_size) {
  if (status == HCI_ERR_INSUFFCIENT_SECURITY) {
    /* If remote device stop the encryption before we call "Read Encryption Key
     * Size", we might receive Insufficient Security, which means that link is
     * no longer encrypted. */
    LOG(INFO) << __func__ << ": encryption stopped on link: " << loghex(handle);
    return;
  }

  if (status != HCI_SUCCESS) {
    LOG(INFO) << __func__ << ": disconnecting, status: " << loghex(status);
    acl_disconnect_from_handle(handle, HCI_ERR_PEER_USER,
                               "stack::btu_hcif Key size fail");
    return;
  }

  if (key_size < MIN_KEY_SIZE) {
    LOG(ERROR) << __func__
               << " encryption key too short, disconnecting. handle: "
               << loghex(handle) << " key_size: " << +key_size;

    acl_disconnect_from_handle(handle, HCI_ERR_HOST_REJECT_SECURITY,
                               "stack::btu::btu_hcif::read_encryption_key_size_"
                               "complete_after_key_refresh Key size too small");
    return;
  }

  btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status),
                         1 /* enc_enable */);
}

void btm_sec_encryption_key_refresh_complete(uint16_t handle,
                                             tHCI_STATUS status) {
  if (status != HCI_SUCCESS || BTM_IsBleConnection(handle) ||
      // Skip encryption key size check when using set_min_encryption_key_size
      controller_get_interface()->supports_set_min_encryption_key_size()) {
    btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status),
                           (status == HCI_SUCCESS) ? 1 : 0);
  } else {
    btsnd_hcic_read_encryption_key_size(
        handle,
        base::Bind(&read_encryption_key_size_complete_after_key_refresh));
  }
}

/** This function is called when a new connection link key is generated */
void btm_sec_link_key_notification(const RawAddress& p_bda,
                                   const Octet16& link_key, uint8_t key_type) {
+8 −2
Original line number Diff line number Diff line
@@ -519,7 +519,8 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr,
 * Returns          void
 *
 ******************************************************************************/
void btm_sec_rmt_host_support_feat_evt(const uint8_t* p);
void btm_sec_rmt_host_support_feat_evt(const RawAddress bd_addr,
                                       uint8_t features_0);

/*******************************************************************************
 *
@@ -558,7 +559,8 @@ void btm_io_capabilities_rsp(const tBTM_SP_IO_RSP evt_data);
 * Returns          void
 *
 ******************************************************************************/
void btm_proc_sp_req_evt(tBTM_SP_EVT event, uint8_t* p);
void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda,
                         uint32_t value);

/*******************************************************************************
 *
@@ -677,6 +679,10 @@ void btm_sec_role_changed(tHCI_STATUS hci_status, const RawAddress& bd_addr,
void btm_sec_link_key_notification(const RawAddress& p_bda,
                                   const Octet16& link_key, uint8_t key_type);

/** This function is called for each encryption key refresh complete event */
void btm_sec_encryption_key_refresh_complete(uint16_t handle,
                                             tHCI_STATUS status);

/*******************************************************************************
 *
 * Function         btm_sec_link_key_request
+34 −42
Original line number Diff line number Diff line
@@ -97,8 +97,11 @@ static void btu_hcif_esco_connection_chg_evt(uint8_t* p);

static void btu_hcif_sec_pin_code_request(const uint8_t* p);
static void btu_hcif_sec_link_key_request(const uint8_t* p);
static void btu_hcif_sec_rmt_host_support_feat_evt(const uint8_t* p);
static void btu_hcif_proc_sp_req_evt(tBTM_SP_EVT event, const uint8_t* p);
static void btu_hcif_rem_oob_req(const uint8_t* p);
static void btu_hcif_simple_pair_complete(const uint8_t* p);
static void btu_hcif_proc_sp_req_evt(const tBTM_SP_EVT event, const uint8_t* p);
static void btu_hcif_create_conn_cancel_complete(const uint8_t* p,
                                                 uint16_t evt_len);
static void btu_hcif_read_local_oob_complete(const uint8_t* p,
@@ -300,7 +303,7 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id,
      btm_pm_proc_ssr_evt(p, hci_evt_len);
      break;
    case HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT:
      btm_sec_rmt_host_support_feat_evt(p);
      btu_hcif_sec_rmt_host_support_feat_evt(p);
      break;
    case HCI_IO_CAPABILITY_REQUEST_EVT:
      btu_hcif_io_cap_request_evt(p);
@@ -309,10 +312,10 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id,
      btu_hcif_io_cap_response_evt(p);
      break;
    case HCI_USER_CONFIRMATION_REQUEST_EVT:
      btm_proc_sp_req_evt(BTM_SP_CFM_REQ_EVT, p);
      btu_hcif_proc_sp_req_evt(BTM_SP_CFM_REQ_EVT, p);
      break;
    case HCI_USER_PASSKEY_REQUEST_EVT:
      btm_proc_sp_req_evt(BTM_SP_KEY_REQ_EVT, p);
      btu_hcif_proc_sp_req_evt(BTM_SP_KEY_REQ_EVT, p);
      break;
    case HCI_REMOTE_OOB_DATA_REQUEST_EVT:
      btu_hcif_rem_oob_req(p);
@@ -321,7 +324,7 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id,
      btu_hcif_simple_pair_complete(p);
      break;
    case HCI_USER_PASSKEY_NOTIFY_EVT:
      btm_proc_sp_req_evt(BTM_SP_KEY_NOTIF_EVT, p);
      btu_hcif_proc_sp_req_evt(BTM_SP_KEY_NOTIF_EVT, p);
      break;

    case HCI_BLE_EVENT: {
@@ -1449,6 +1452,31 @@ void btu_hcif_simple_pair_complete(const uint8_t* p) {
  STREAM_TO_BDADDR(bd_addr, p);
  btm_simple_pair_complete(bd_addr, status);
}
void btu_hcif_sec_rmt_host_support_feat_evt(const uint8_t* p) {
  RawAddress bd_addr; /* peer address */
  uint8_t features_0;

  STREAM_TO_BDADDR(bd_addr, p);
  STREAM_TO_UINT8(features_0, p);
  btm_sec_rmt_host_support_feat_evt(bd_addr, features_0);
}
void btu_hcif_proc_sp_req_evt(tBTM_SP_EVT event, const uint8_t* p) {
  RawAddress bda;
  uint32_t value = 0;

  /* All events start with bd_addr */
  STREAM_TO_BDADDR(bda, p);
  switch (event) {
    case BTM_SP_CFM_REQ_EVT:
    case BTM_SP_KEY_NOTIF_EVT:
      STREAM_TO_UINT32(value, p);
      break;
    case BTM_SP_KEY_REQ_EVT:
      // No value needed.
      break;
  }
  btm_proc_sp_req_evt(event, bda, value);
}
void btu_hcif_create_conn_cancel_complete(const uint8_t* p, uint16_t evt_len) {
  uint8_t status;

@@ -1580,36 +1608,6 @@ static void btu_hcif_io_cap_response_evt(const uint8_t* p) {
 * End of Simple Pairing Events
 **********************************************/

static void read_encryption_key_size_complete_after_key_refresh(uint8_t status, uint16_t handle, uint8_t key_size) {
  if (status == HCI_ERR_INSUFFCIENT_SECURITY) {
    /* If remote device stop the encryption before we call "Read Encryption Key
     * Size", we might receive Insufficient Security, which means that link is
     * no longer encrypted. */
    LOG(INFO) << __func__ << ": encryption stopped on link: " << loghex(handle);
    return;
  }

  if (status != HCI_SUCCESS) {
    LOG(INFO) << __func__ << ": disconnecting, status: " << loghex(status);
    acl_disconnect_from_handle(handle, HCI_ERR_PEER_USER,
                               "stack::btu_hcif Key size fail");
    return;
  }

  if (key_size < MIN_KEY_SIZE) {
    LOG(ERROR) << __func__ << " encryption key too short, disconnecting. handle: " << loghex(handle)
               << " key_size: " << +key_size;

    acl_disconnect_from_handle(handle, HCI_ERR_HOST_REJECT_SECURITY,
                               "stack::btu::btu_hcif::read_encryption_key_size_"
                               "complete_after_key_refresh Key size too small");
    return;
  }

  btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status),
                         1 /* enc_enable */);
}

static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p) {
  uint8_t status;
  uint16_t handle;
@@ -1617,14 +1615,8 @@ static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p) {
  STREAM_TO_UINT8(status, p);
  STREAM_TO_UINT16(handle, p);

  if (status != HCI_SUCCESS || BTM_IsBleConnection(handle) ||
      // Skip encryption key size check when using set_min_encryption_key_size
      controller_get_interface()->supports_set_min_encryption_key_size()) {
    btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status),
                           (status == HCI_SUCCESS) ? 1 : 0);
  } else {
    btsnd_hcic_read_encryption_key_size(handle, base::Bind(&read_encryption_key_size_complete_after_key_refresh));
  }
  btm_sec_encryption_key_refresh_complete(handle,
                                          static_cast<tHCI_STATUS>(status));
}

/**********************************************
+6 −2
Original line number Diff line number Diff line
@@ -28,18 +28,22 @@
void btm_create_conn_cancel_complete(uint8_t status, const RawAddress bd_addr);
void btm_io_capabilities_req(RawAddress p);
void btm_io_capabilities_rsp(const tBTM_SP_IO_RSP evt_data);
void btm_proc_sp_req_evt(tBTM_SP_EVT event, const uint8_t* p);
void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda,
                         uint32_t value);
void btm_read_local_oob_complete(const tBTM_SP_LOC_OOB evt_data);
void btm_rem_oob_req(const RawAddress bd_addr);
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);
void btm_sec_encryption_key_refresh_complete(uint16_t handle,
                                             tHCI_STATUS status);
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 RawAddress bda);
void btm_sec_pin_code_request(const RawAddress p_bda);
void btm_sec_rmt_host_support_feat_evt(const uint8_t* p);
void btm_sec_rmt_host_support_feat_evt(const RawAddress bd_addr,
                                       uint8_t features_0);
void btm_sec_rmt_name_request_complete(const RawAddress* bd_addr,
                                       const uint8_t* bd_name,
                                       tHCI_STATUS status);
Loading