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

Commit 3127750e authored by Myles Watson's avatar Myles Watson
Browse files

btm_sec: Move encryption key checks out of btu

Bug: 301661850
Test: mma -j32
Change-Id: I60f9fb2c0138f9c0f13ec950e3b0406e2fc15048
parent 79ae1efe
Loading
Loading
Loading
Loading
+49 −0
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"
@@ -3999,6 +4000,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) {
+4 −0
Original line number Diff line number Diff line
@@ -678,6 +678,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
+2 −38
Original line number Diff line number Diff line
@@ -1598,36 +1598,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;
@@ -1635,14 +1605,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));
}

/**********************************************
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ 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);
+10 −1
Original line number Diff line number Diff line
@@ -25,7 +25,8 @@
#include <cstdint>
#include <string>

#include "btm_sec_api_types.h"
#include "stack/include/btm_sec_api_types.h"
#include "stack/include/btm_status.h"
#include "test/common/mock_functions.h"
#include "types/raw_address.h"

@@ -96,6 +97,8 @@ struct btm_sec_l2cap_access_req btm_sec_l2cap_access_req;
struct btm_sec_l2cap_access_req_by_requirement
    btm_sec_l2cap_access_req_by_requirement;
struct btm_sec_link_key_notification btm_sec_link_key_notification;
struct btm_sec_encryption_key_refresh_complete
    btm_sec_encryption_key_refresh_complete;
struct btm_sec_link_key_request btm_sec_link_key_request;
struct btm_sec_mx_access_request btm_sec_mx_access_request;
struct btm_sec_pin_code_request btm_sec_pin_code_request;
@@ -424,6 +427,12 @@ void btm_sec_link_key_notification(const RawAddress& p_bda,
  test::mock::stack_btm_sec::btm_sec_link_key_notification(p_bda, link_key,
                                                           key_type);
}
void btm_sec_encryption_key_refresh_complete(uint16_t handle,
                                             tHCI_STATUS status) {
  inc_func_call_count(__func__);
  test::mock::stack_btm_sec::btm_sec_encryption_key_refresh_complete(handle,
                                                                     status);
}
void btm_sec_link_key_request(const RawAddress bda) {
  inc_func_call_count(__func__);
  test::mock::stack_btm_sec::btm_sec_link_key_request(bda);
Loading