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

Commit debcc0d6 authored by Chris Manton's avatar Chris Manton Committed by Automerger Merge Worker
Browse files

Streamline stack/btm/btm_sec::btm_sec_encrypt_change am: 66708b1b am: d33563ab am: 83cd7b3f

parents 5e62ae0a 83cd7b3f
Loading
Loading
Loading
Loading
+44 −27
Original line number Diff line number Diff line
@@ -3210,7 +3210,6 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status) {
 ******************************************************************************/
void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status,
                            uint8_t encr_enable) {
  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle);
  /* For transaction collision we need to wait and repeat.  There is no need */
  /* for random timeout because only peripheral should receive the result */
  if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) ||
@@ -3220,7 +3219,17 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status,
  }
  btm_cb.collision_start_time = 0;

  if (!p_dev_rec) return;
  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle);
  if (p_dev_rec == nullptr) {
    LOG_WARN(
        "Received encryption change for unknown device handle:0x%04x status:%s "
        "enable:0x%x",
        handle, hci_status_code_text(status).c_str(), encr_enable);
    return;
  }

  const tBT_TRANSPORT transport =
      BTM_IsBleConnection(handle) ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR;

  LOG_DEBUG(
      "Security Manager encryption change request hci_status:%s"
@@ -3230,37 +3239,46 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status,
      (p_dev_rec->sec_state) ? "encrypted" : "unencrypted",
      p_dev_rec->sec_flags);

  if ((status == HCI_SUCCESS) && encr_enable) {
    if (p_dev_rec->hci_handle == handle) {
  if (status == HCI_SUCCESS) {
    if (encr_enable) {
      if (p_dev_rec->hci_handle == handle) {  // classic
        p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
        if (p_dev_rec->pin_code_length >= 16 ||
            p_dev_rec->link_key_type == BTM_LKEY_TYPE_AUTH_COMB ||
            p_dev_rec->link_key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256) {
          p_dev_rec->sec_flags |= BTM_SEC_16_DIGIT_PIN_AUTHED;
        }
      } else if (p_dev_rec->ble_hci_handle == handle) {  // BLE
        p_dev_rec->sec_flags |=
            (BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED);
      } else {
      p_dev_rec->sec_flags |= (BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED);
        LOG_ERROR(
            "Received encryption change for unknown device handle:0x%04x "
            "status:%s enable:0x%x",
            handle, hci_status_code_text(status).c_str(), encr_enable);
      }
  }

    } else {
      /* It is possible that we decrypted the link to perform role switch */
  /* mark link not to be encrypted, so that when we execute security next time
   * it will kick in again */
  if ((status == HCI_SUCCESS) && !encr_enable) {
    if (p_dev_rec->hci_handle == handle)
      /* mark link not to be encrypted, so that when we execute security next
       * time it will kick in again */
      if (p_dev_rec->hci_handle == handle) {  // clasic
        p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED;
    else
      } else if (p_dev_rec->ble_hci_handle == handle) {  // BLE
        p_dev_rec->sec_flags &= ~BTM_SEC_LE_ENCRYPTED;
      } else {
        LOG_ERROR(
            "Received encryption change for unknown device handle:0x%04x "
            "status:%s enable:0x%x",
            handle, hci_status_code_text(status).c_str(), encr_enable);
      }
    }
  }

  BTM_TRACE_DEBUG("after update p_dev_rec->sec_flags=0x%x",
                  p_dev_rec->sec_flags);
  LOG_DEBUG("after update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags);

  auto transport =
      BTM_IsBleConnection(handle) ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR;
  btm_sec_check_pending_enc_req(p_dev_rec, transport, encr_enable);

  if (BTM_IsBleConnection(handle)) {
  if (transport == BT_TRANSPORT_LE) {
    if (status == HCI_ERR_KEY_MISSING || status == HCI_ERR_AUTH_FAILURE ||
        status == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) {
      p_dev_rec->sec_flags &= ~(BTM_SEC_LE_LINK_KEY_KNOWN);
@@ -3274,8 +3292,7 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status,
    p_dev_rec->enc_key_size = 16;
  }

  BTM_TRACE_DEBUG("in %s new_encr_key_256 is %d", __func__,
                  p_dev_rec->new_encryption_key_is_p256);
  LOG_DEBUG("in new_encr_key_256 is %d", p_dev_rec->new_encryption_key_is_p256);

  if ((status == HCI_SUCCESS) && encr_enable &&
      (p_dev_rec->hci_handle == handle)) {
+71 −0
Original line number Diff line number Diff line
@@ -35,11 +35,14 @@
#include "stack/btm/btm_int_types.h"
#include "stack/btm/btm_sco.h"
#include "stack/btm/btm_sec.h"
#include "stack/btm/security_device_record.h"
#include "stack/include/acl_api.h"
#include "stack/include/acl_hci_link_interface.h"
#include "stack/include/btm_client_interface.h"
#include "stack/include/hcidefs.h"
#include "stack/include/sec_hci_link_interface.h"
#include "stack/l2cap/l2c_int.h"
#include "test/mock/mock_osi_list.h"
#include "test/mock/mock_stack_hcic_hcicmds.h"
#include "types/raw_address.h"

@@ -112,6 +115,13 @@ class StackBtmTest : public Test {
  void TearDown() override {}
};

class StackBtmWithInitFreeTest : public StackBtmTest {
 public:
 protected:
  void SetUp() override { btm_cb.Init(BTM_SEC_MODE_SC); }
  void TearDown() override { btm_cb.Free(); }
};

TEST_F(StackBtmTest, GlobalLifecycle) {
  get_btm_client_interface().lifecycle.btm_init();
  get_btm_client_interface().lifecycle.btm_free();
@@ -122,6 +132,11 @@ TEST_F(StackBtmTest, DynamicLifecycle) {
  delete btm;
}

TEST_F(StackBtmTest, InitFree) {
  btm_cb.Init(0x1);
  btm_cb.Free();
}

TEST_F(StackBtmTest, tSCO_CB) {
  bluetooth::common::InitFlags::SetAllForTesting();
  tSCO_CB* p_sco = &btm_cb.sco_cb;
@@ -263,3 +278,59 @@ TEST(SecTest, btm_sec_rmt_name_request_complete) {

  btm_cb.Free();
}

TEST_F(StackBtmWithInitFreeTest, btm_sec_encrypt_change) {
  bluetooth::common::InitFlags::SetAllForTesting();

  RawAddress bd_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
  const uint16_t classic_handle = 0x1234;
  const uint16_t ble_handle = 0x9876;

  // Check the collision conditionals
  btm_cb.collision_start_time = 0UL;
  btm_sec_encrypt_change(classic_handle, HCI_ERR_LMP_ERR_TRANS_COLLISION, 0x01);
  uint64_t collision_start_time = btm_cb.collision_start_time;
  ASSERT_NE(0UL, collision_start_time);

  btm_cb.collision_start_time = 0UL;
  btm_sec_encrypt_change(classic_handle, HCI_ERR_DIFF_TRANSACTION_COLLISION,
                         0x01);
  collision_start_time = btm_cb.collision_start_time;
  ASSERT_NE(0UL, collision_start_time);

  // No device
  btm_cb.collision_start_time = 0;
  btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x01);
  ASSERT_EQ(0UL, btm_cb.collision_start_time);

  // Setup device
  tBTM_SEC_DEV_REC* device_record = btm_sec_allocate_dev_rec();
  ASSERT_NE(nullptr, device_record);
  ASSERT_EQ(BTM_SEC_IN_USE, device_record->sec_flags);
  device_record->bd_addr = bd_addr;
  device_record->hci_handle = classic_handle;
  device_record->ble_hci_handle = ble_handle;

  // With classic device encryption enable
  btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x01);
  ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED,
            device_record->sec_flags);

  // With classic device encryption disable
  btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x00);
  ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_AUTHENTICATED, device_record->sec_flags);
  device_record->sec_flags = BTM_SEC_IN_USE;

  // With le device encryption enable
  btm_sec_encrypt_change(ble_handle, HCI_SUCCESS, 0x01);
  ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED,
            device_record->sec_flags);

  // With le device encryption disable
  btm_sec_encrypt_change(ble_handle, HCI_SUCCESS, 0x00);
  ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_LE_AUTHENTICATED,
            device_record->sec_flags);
  device_record->sec_flags = BTM_SEC_IN_USE;

  wipe_secrets_and_remove(device_record);
}