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

Commit d429903c authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "RootCanal: Add LeEncryption LinkLayer Packets"

parents c5068d7e baf3642a
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -2000,15 +2000,12 @@ void DualModeController::LeStartEncryption(CommandPacketView command) {
      gd_hci::LeSecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());

  uint16_t handle = command_view.GetConnectionHandle();

  auto status_packet = bluetooth::hci::LeStartEncryptionStatusBuilder::Create(
      ErrorCode::SUCCESS, kNumCommandPackets);
  send_event_(std::move(status_packet));
  ErrorCode status = link_layer_controller_.LeEnableEncryption(
      command_view.GetConnectionHandle(), command_view.GetRand(),
      command_view.GetEdiv(), command_view.GetLtk());

  auto complete_packet = bluetooth::hci::EncryptionChangeBuilder::Create(
      ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::OFF);
  send_event_(std::move(complete_packet));
  send_event_(bluetooth::hci::LeStartEncryptionStatusBuilder::Create(
      status, kNumCommandPackets));
}

void DualModeController::ReadLoopbackMode(CommandPacketView command) {
+89 −0
Original line number Diff line number Diff line
@@ -212,6 +212,12 @@ void LinkLayerController::IncomingPacket(
    case model::packets::PacketType::LE_CONNECT_COMPLETE:
      IncomingLeConnectCompletePacket(incoming);
      break;
    case model::packets::PacketType::LE_ENCRYPT_CONNECTION:
      IncomingLeEncryptConnection(incoming);
      break;
    case model::packets::PacketType::LE_ENCRYPT_CONNECTION_RESPONSE:
      IncomingLeEncryptConnectionResponse(incoming);
      break;
    case model::packets::PacketType::LE_SCAN:
      // TODO: Check Advertising flags and see if we are scannable.
      IncomingLeScanPacket(incoming);
@@ -897,6 +903,61 @@ void LinkLayerController::IncomingLeConnectCompletePacket(
      complete.GetLeConnectionSupervisionTimeout());
}

void LinkLayerController::IncomingLeEncryptConnection(
    model::packets::LinkLayerPacketView incoming) {
  LOG_INFO();

  // TODO: Check keys
  Address peer = incoming.GetSourceAddress();
  uint16_t handle = connections_.GetHandleOnlyAddress(peer);
  if (handle == acl::kReservedHandle) {
    LOG_INFO("@%s: Unknown connection @%s",
             incoming.GetDestinationAddress().ToString().c_str(),
             peer.ToString().c_str());
    return;
  }
  ErrorCode status = ErrorCode::SUCCESS;
  auto le_encrypt = model::packets::LeEncryptConnectionView::Create(incoming);
  ASSERT(le_encrypt.IsValid());

  if (connections_.IsEncrypted(handle)) {
    send_event_(bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
        status, handle));
  } else {
    connections_.Encrypt(handle);
    send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
        status, handle, bluetooth::hci::EncryptionEnabled::ON));
  }
  SendLeLinkLayerPacket(
      model::packets::LeEncryptConnectionResponseBuilder::Create(
          connections_.GetOwnAddress(handle).GetAddress(), peer,
          le_encrypt.GetRand(), le_encrypt.GetEdiv(), le_encrypt.GetLtk()));
}

void LinkLayerController::IncomingLeEncryptConnectionResponse(
    model::packets::LinkLayerPacketView incoming) {
  LOG_INFO();
  // TODO: Check keys
  uint16_t handle =
      connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
  if (handle == acl::kReservedHandle) {
    LOG_INFO("@%s: Unknown connection @%s",
             incoming.GetDestinationAddress().ToString().c_str(),
             incoming.GetSourceAddress().ToString().c_str());
    return;
  }
  ErrorCode status = ErrorCode::SUCCESS;

  if (connections_.IsEncrypted(handle)) {
    send_event_(bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
        status, handle));
  } else {
    connections_.Encrypt(handle);
    send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
        status, handle, bluetooth::hci::EncryptionEnabled::ON));
  }
}

void LinkLayerController::IncomingLeScanPacket(
    model::packets::LinkLayerPacketView incoming) {
  auto to_send = model::packets::LeScanResponseBuilder::Create(
@@ -1722,6 +1783,34 @@ void LinkLayerController::LeSetPrivacyMode(uint8_t address_type, Address addr,
  LOG_INFO("mode = %d ", mode);
}

void LinkLayerController::HandleLeEnableEncryption(
    uint16_t handle, std::array<uint8_t, 8> rand, uint16_t ediv,
    std::array<uint8_t, 16> ltk) {
  // TODO: Check keys
  // TODO: Block ACL traffic or at least guard against it
  if (!connections_.HasHandle(handle)) {
    return;
  }
  SendLeLinkLayerPacket(model::packets::LeEncryptConnectionBuilder::Create(
      connections_.GetOwnAddress(handle).GetAddress(),
      connections_.GetAddress(handle).GetAddress(), rand, ediv, ltk));
}

ErrorCode LinkLayerController::LeEnableEncryption(uint16_t handle,
                                                  std::array<uint8_t, 8> rand,
                                                  uint16_t ediv,
                                                  std::array<uint8_t, 16> ltk) {
  if (!connections_.HasHandle(handle)) {
    LOG_INFO("Unknown handle %04x", handle);
    return ErrorCode::UNKNOWN_CONNECTION;
  }

  ScheduleTask(milliseconds(5), [this, handle, rand, ediv, ltk]() {
    HandleLeEnableEncryption(handle, rand, ediv, ltk);
  });
  return ErrorCode::SUCCESS;
}

void LinkLayerController::LeWhiteListRemoveDevice(Address addr,
                                                  uint8_t addr_type) {
  // TODO: Add checks to see if advertising, scanning, or a connection request
+9 −0
Original line number Diff line number Diff line
@@ -153,6 +153,12 @@ class LinkLayerController {
  bool LeResolvingListFull();
  void LeSetPrivacyMode(uint8_t address_type, Address addr, uint8_t mode);

  void HandleLeEnableEncryption(uint16_t handle, std::array<uint8_t, 8> rand,
                                uint16_t ediv, std::array<uint8_t, 16> ltk);

  ErrorCode LeEnableEncryption(uint16_t handle, std::array<uint8_t, 8> rand,
                               uint16_t ediv, std::array<uint8_t, 16> ltk);

  ErrorCode SetLeAdvertisingEnable(uint8_t le_advertising_enable) {
    le_advertising_enable_ = le_advertising_enable;
    // TODO: Check properties and return errors
@@ -273,6 +279,9 @@ class LinkLayerController {
  void IncomingLeConnectPacket(model::packets::LinkLayerPacketView packet);
  void IncomingLeConnectCompletePacket(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeEncryptConnection(model::packets::LinkLayerPacketView packet);
  void IncomingLeEncryptConnectionResponse(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeScanPacket(model::packets::LinkLayerPacketView packet);
  void IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView packet);
  void IncomingPagePacket(model::packets::LinkLayerPacketView packet);
+14 −11
Original line number Diff line number Diff line
@@ -36,8 +36,8 @@ enum PacketType : 8 {
    REMOTE_NAME_REQUEST = 0x1D,
    REMOTE_NAME_REQUEST_RESPONSE = 0x1E,
    SCO = 0x1F,
    COMMAND = 0x23, // Remove
    RESPONSE = 0x24, // Remove
    LE_ENCRYPT_CONNECTION = 0x20,
    LE_ENCRYPT_CONNECTION_RESPONSE = 0x21,
}

packet LinkLayerPacket {
@@ -47,15 +47,6 @@ packet LinkLayerPacket {
  _body_,
}

packet Command : LinkLayerPacket (type = COMMAND) {
  _payload_,
}

packet Response : LinkLayerPacket (type = RESPONSE) {
  opcode : 16,
  _payload_,
}

packet AclPacket : LinkLayerPacket (type = ACL) {
  _payload_,
}
@@ -234,3 +225,15 @@ packet ScoPacket : LinkLayerPacket (type = SCO) {
  _payload_,
}

packet LeEncryptConnection : LinkLayerPacket (type = LE_ENCRYPT_CONNECTION) {
  rand : 8[8],
  ediv : 16,
  ltk : 8[16],
}

packet LeEncryptConnectionResponse : LinkLayerPacket (type = LE_ENCRYPT_CONNECTION_RESPONSE) {
  rand : 8[8],
  ediv : 16,
  ltk : 8[16],
}