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

Commit e85f2925 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Automerger Merge Worker
Browse files

Properly process the LE Long Term Key Request am: ca90aba4

Original change: https://android-review.googlesource.com/c/platform/system/bt/+/1406070

Change-Id: If5def9c75ecdc350ac93d80303b5f4ddcc2b04e1
parents 3095619a ca90aba4
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -338,10 +338,27 @@ void SecurityManagerImpl::OnEncryptionChange(hci::Address address, bool encrypte
}

void SecurityManagerImpl::OnHciLeEvent(hci::LeMetaEventView event) {
  // hci::SubeventCode::LONG_TERM_KEY_REQUEST,
  hci::SubeventCode code = event.GetSubeventCode();

  if (code == hci::SubeventCode::LONG_TERM_KEY_REQUEST) {
    hci::LeLongTermKeyRequestView le_long_term_key_request_view = hci::LeLongTermKeyRequestView::Create(event);
    if (!le_long_term_key_request_view.IsValid()) {
      LOG_ERROR("Invalid LeLongTermKeyRequestView packet received");
      return;
    }

    if (le_long_term_key_request_view.GetConnectionHandle() == pending_le_pairing_.connection_handle_) {
      pending_le_pairing_.handler_->OnHciLeEvent(event);
      return;
    }

    LOG_INFO("Unhandled HCI LE security event, code %s", hci::SubeventCodeText(code).c_str());
    return;
  }

  // hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE,
  // hci::SubeventCode::GENERATE_DHKEY_COMPLETE,
  LOG_ERROR("Unhandled HCI LE security event");
  LOG_ERROR("Unhandled HCI LE security event, code %s", hci::SubeventCodeText(code).c_str());
}

void SecurityManagerImpl::OnPairingPromptAccepted(const bluetooth::hci::AddressWithType& address, bool confirmed) {
+6 −1
Original line number Diff line number Diff line
@@ -113,8 +113,10 @@ void PairingHandlerLe::PairingMain(InitialInformations i) {
    if (IAmMaster(i)) {
      LOG_INFO("Sending start encryption request");
      SendHciLeStartEncryption(i, i.connection_handle, {0}, {0}, ltk);
    } else {
      auto ltk_req = WaitLeLongTermKeyRequest();
      SendHciLeLongTermKeyReply(i, i.connection_handle, ltk);
    }

  } else {
    // 2.3.5.5 LE legacy pairing phase 2
    LOG_INFO("Pairing Phase 2 LE legacy pairing Started");
@@ -138,6 +140,9 @@ void PairingHandlerLe::PairingMain(InitialInformations i) {
    if (IAmMaster(i)) {
      LOG_INFO("Sending start encryption request");
      SendHciLeStartEncryption(i, i.connection_handle, {0}, {0}, stk);
    } else {
      auto ltk_req = WaitLeLongTermKeyRequest();
      SendHciLeLongTermKeyReply(i, i.connection_handle, stk);
    }
  }

+40 −0
Original line number Diff line number Diff line
@@ -145,6 +145,12 @@ class PairingHandlerLe {
                                            }));
  }

  void SendHciLeLongTermKeyReply(const InitialInformations& i, uint16_t conn_handle, const Octet16& ltk) {
    i.le_security_interface->EnqueueCommand(
        hci::LeLongTermKeyRequestReplyBuilder::Create(conn_handle, ltk),
        i.l2cap_handler->BindOnce([](hci::CommandCompleteView) {}));
  }

  std::variant<PairingFailure, EncryptionChangeView, EncryptionKeyRefreshCompleteView> WaitEncryptionChanged() {
    PairingEvent e = WaitForEvent();
    if (e.type != PairingEvent::HCI_EVENT) return PairingFailure("Was expecting HCI event but received something else");
@@ -170,6 +176,31 @@ class PairingHandlerLe {
    return PairingFailure("Was expecting Encryption Change or Key Refresh Complete but received something else");
  }

  std::variant<PairingFailure, hci::LeLongTermKeyRequestView> WaitLeLongTermKeyRequest() {
    PairingEvent e = WaitForEvent();
    if (e.type != PairingEvent::HCI_EVENT) return PairingFailure("Was expecting HCI event but received something else");

    if (!e.hci_event->IsValid()) return PairingFailure("Received invalid HCI event");

    if (e.hci_event->GetEventCode() != hci::EventCode::LE_META_EVENT) return PairingFailure("Was expecting LE event");

    hci::LeMetaEventView le_event = hci::LeMetaEventView::Create(*e.hci_event);
    if (!le_event.IsValid()) {
      return PairingFailure("Invalid LE Event received");
    }

    if (le_event.GetSubeventCode() != hci::SubeventCode::LONG_TERM_KEY_REQUEST) {
      return PairingFailure("Was expecting Long Term Key Request");
    }

    hci::LeLongTermKeyRequestView ltk_req_packet = hci::LeLongTermKeyRequestView::Create(le_event);
    if (!ltk_req_packet.IsValid()) {
      return PairingFailure("Invalid LE Long Term Key Request received");
    }

    return ltk_req_packet;
  }

  inline bool IAmMaster(const InitialInformations& i) {
    return i.my_role == hci::Role::MASTER;
  }
@@ -259,6 +290,15 @@ class PairingHandlerLe {
    pairing_thread_blocker_.notify_one();
  }

  /* HCI LE event received from remote device */
  void OnHciLeEvent(hci::LeMetaEventView hci_event) {
    {
      std::unique_lock<std::mutex> lock(queue_guard);
      queue.push(PairingEvent(std::move(hci_event)));
    }
    pairing_thread_blocker_.notify_one();
  }

  /* Blocks the pairing process until some external interaction, or timeout happens */
  PairingEvent WaitForEvent() {
    std::unique_lock<std::mutex> lock(queue_guard);
+3 −0
Original line number Diff line number Diff line
@@ -261,6 +261,9 @@ class PairingHandlerPairTest : public testing::Test {
          pairing_handler_a->OnHciEvent(EventBuilderToView(
              EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, CONN_HANDLE_MASTER, EncryptionEnabled::ON)));

          pairing_handler_b->OnHciEvent(EventBuilderToView(
              hci::LeLongTermKeyRequestBuilder::Create(CONN_HANDLE_SLAVE, {0,0,0,0,0,0,0,0}, 0)));

          pairing_handler_b->OnHciEvent(EventBuilderToView(
              EncryptionChangeBuilder::Create(ErrorCode::SUCCESS, CONN_HANDLE_SLAVE, EncryptionEnabled::ON)));
        });