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

Commit 3309f597 authored by Hansong Zhang's avatar Hansong Zhang
Browse files

Introduce L2cap security shim

L2cap security shim lets GD L2cap wants to enforce security requirements
on legacy security module.

Implementing the GD security interface.

Tag: #gd-refactor
Bug: 141555841
Test: cert/run --host
Test: Pair and connect with a headset
Change-Id: I60cd99566011f3eb93ecd6b32b1f428e8d69733d
parent 14b84f92
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -98,6 +98,10 @@ void InitFlags::Load(const char** flags) {
  if (gd_acl_enabled && !gd_controller_enabled) {
    gd_controller_enabled = true;
  }
  if (gd_l2cap_enabled) {
    gd_acl_enabled = false;
    gd_hci_enabled = true;
  }
  if (gd_controller_enabled && !gd_hci_enabled) {
    gd_hci_enabled = true;
  }
+14 −14
Original line number Diff line number Diff line
@@ -48,6 +48,20 @@ class L2capClassicModule : public bluetooth::Module {
  virtual std::unique_ptr<DynamicChannelManager> GetDynamicChannelManager();

  static const ModuleFactory Factory;
  /**
   * Only for the classic security module to inject functionality to enforce security level for a connection. When
   * classic security module is stopping, inject nullptr. Note: We expect this only to be called during stack startup.
   * This is not synchronized.
   */
  virtual void InjectSecurityEnforcementInterface(SecurityEnforcementInterface* security_enforcement_interface);

  /**
   * Get the interface for Security Module to access link function.
   * Security Module needs to register the callback for ACL link connected and disconnected. When connected, either by
   * incoming or by outgoing connection request, Security Module receives a LinkSecurityInterface proxy, which can be
   * used to access some link functionlities.
   */
  virtual SecurityInterface* GetSecurityInterface(os::Handler* handler, LinkSecurityInterfaceListener* listener);

 protected:
  void ListDependencies(ModuleList* list) override;
@@ -65,20 +79,6 @@ class L2capClassicModule : public bluetooth::Module {
  std::unique_ptr<impl> pimpl_;

  friend security::SecurityModule;
  /**
   * Only for the classic security module to inject functionality to enforce security level for a connection. When
   * classic security module is stopping, inject nullptr. Note: We expect this only to be called during stack startup.
   * This is not synchronized.
   */
  virtual void InjectSecurityEnforcementInterface(SecurityEnforcementInterface* security_enforcement_interface);

  /**
   * Get the interface for Security Module to access link function.
   * Security Module needs to register the callback for ACL link connected and disconnected. When connected, either by
   * incoming or by outgoing connection request, Security Module receives a LinkSecurityInterface proxy, which can be
   * used to access some link functionlities.
   */
  virtual SecurityInterface* GetSecurityInterface(os::Handler* handler, LinkSecurityInterfaceListener* listener);

  DISALLOW_COPY_AND_ASSIGN(L2capClassicModule);
};
+0 −51
Original line number Diff line number Diff line
@@ -1343,54 +1343,3 @@ tBTM_STATUS bluetooth::shim::BTM_SetDeviceClass(DEV_CLASS dev_class) {
  LOG_WARN("Unimplemented");
  return BTM_SUCCESS;
}

static std::unordered_map<intptr_t,
                          bluetooth::common::ContextualOnceCallback<void(bool)>>
    security_enforce_callback_map;
static intptr_t security_enforce_callback_counter = 0;

static void security_enforce_result_callback(const RawAddress* bd_addr,
                                             tBT_TRANSPORT trasnport,
                                             void* p_ref_data,
                                             tBTM_STATUS result) {
  intptr_t counter = (intptr_t)p_ref_data;
  if (security_enforce_callback_map.count(security_enforce_callback_counter) ==
      0) {
    LOG(ERROR) << __func__ << "Unknown callback";
    return;
  }
  auto& callback = security_enforce_callback_map[counter];
  std::move(callback).Invoke(result == BTM_SUCCESS);
  security_enforce_callback_map.erase(counter);
}

class SecurityEnforcementShim
    : public bluetooth::l2cap::classic::SecurityEnforcementInterface {
 public:
  void Enforce(bluetooth::hci::AddressWithType remote,
               bluetooth::l2cap::classic::SecurityPolicy policy,
               ResultCallback result_callback) override {
    uint16_t sec_mask = 0;
    switch (policy) {
      case bluetooth::l2cap::classic::SecurityPolicy::
          _SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK:
        break;
      case bluetooth::l2cap::classic::SecurityPolicy::ENCRYPTED_TRANSPORT:
        sec_mask = BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT |
                   BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT;
        break;
      case bluetooth::l2cap::classic::SecurityPolicy::BEST:
      case bluetooth::l2cap::classic::SecurityPolicy::
          AUTHENTICATED_ENCRYPTED_TRANSPORT:
        sec_mask = BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT |
                   BTM_SEC_IN_MITM | BTM_SEC_OUT_AUTHENTICATE |
                   BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_MITM;
        break;
    }
    auto bd_addr = bluetooth::ToRawAddress(remote.GetAddress());
    btm_sec_l2cap_access_req_by_requirement(
        bd_addr, sec_mask, true, security_enforce_result_callback,
        (void*)security_enforce_callback_counter);
    security_enforce_callback_counter++;
  }
};
+6 −0
Original line number Diff line number Diff line
@@ -81,6 +81,12 @@ L2cap* GetL2cap() {
  return Stack::GetInstance()->GetStackManager()->GetInstance<L2cap>();
}

l2cap::classic::L2capClassicModule* GetL2capClassicModule() {
  return Stack::GetInstance()
      ->GetStackManager()
      ->GetInstance<bluetooth::l2cap::classic::L2capClassicModule>();
}

bluetooth::l2cap::le::L2capLeModule* GetL2capLeModule() {
  return Stack::GetInstance()
      ->GetStackManager()
+4 −0
Original line number Diff line number Diff line
@@ -52,6 +52,9 @@ class LeScanningManager;
}

namespace l2cap {
namespace classic {
class L2capClassicModule;
}  // namespace classic
namespace le {
class L2capLeModule;
}  // namespace le
@@ -77,6 +80,7 @@ Dumpsys* GetDumpsys();
neighbor::InquiryModule* GetInquiry();
hci::HciLayer* GetHciLayer();
L2cap* GetL2cap();
l2cap::classic::L2capClassicModule* GetL2capClassicModule();
l2cap::le::L2capLeModule* GetL2capLeModule();
neighbor::NameModule* GetName();
neighbor::PageModule* GetPage();
Loading