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

Commit 5b4f65e3 authored by Myles Watson's avatar Myles Watson
Browse files

RootCanal: Add Passkey and PasskeyFailed

Bug: 162984360
Tag: #gd-refactor
Test: cert/run --host SecurityTest
Change-Id: I54f2fb20bf1a071b60c9e621ca40d9e850268909
parent 98f53bd3
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ DualModeController::DualModeController(const std::string& properties_filename, u
              RemoteOobExtendedDataRequestReply);
  SET_HANDLER(OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL,
              ReadInquiryResponseTransmitPowerLevel);
  SET_HANDLER(OpCode::SEND_KEYPRESS_NOTIFICATION, SendKeypressNotification);
  SET_HANDLER(OpCode::READ_LOCAL_OOB_DATA, ReadLocalOobData);
  SET_HANDLER(OpCode::READ_LOCAL_OOB_EXTENDED_DATA, ReadLocalOobExtendedData);
  SET_HANDLER(OpCode::WRITE_SIMPLE_PAIRING_MODE, WriteSimplePairingMode);
@@ -711,6 +712,7 @@ void DualModeController::PinCodeRequestNegativeReply(

  send_event_(std::move(packet));
}

void DualModeController::UserPasskeyRequestReply(CommandPacketView command) {
  auto command_view = gd_hci::UserPasskeyRequestReplyView::Create(
      gd_hci::SecurityCommandView::Create(command));
@@ -821,6 +823,19 @@ void DualModeController::ReadInquiryResponseTransmitPowerLevel(
  send_event_(std::move(packet));
}

void DualModeController::SendKeypressNotification(CommandPacketView command) {
  auto command_view = gd_hci::SendKeypressNotificationView::Create(
      gd_hci::SecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());

  auto peer = command_view.GetBdAddr();

  auto status = link_layer_controller_.SendKeypressNotification(
      peer, command_view.GetNotificationType());
  send_event_(bluetooth::hci::SendKeypressNotificationCompleteBuilder::Create(
      kNumCommandPackets, status, peer));
}

void DualModeController::ReadLocalOobData(CommandPacketView command) {
  auto command_view = gd_hci::ReadLocalOobDataView::Create(
      gd_hci::SecurityCommandView::Create(command));
+3 −0
Original line number Diff line number Diff line
@@ -334,6 +334,9 @@ class DualModeController : public Device {
  // 7.3.61
  void ReadInquiryResponseTransmitPowerLevel(CommandPacketView args);

  // 7.3.63
  void SendKeypressNotification(CommandPacketView args);

  // 7.3.79
  void WriteLeHostSupport(CommandPacketView args);

+96 −27
Original line number Diff line number Diff line
@@ -238,6 +238,9 @@ void LinkLayerController::IncomingPacket(
    case PacketType::ISO_CONNECTION_RESPONSE:
      IncomingIsoConnectionResponsePacket(incoming);
      break;
    case PacketType::KEYPRESS_NOTIFICATION:
      IncomingKeypressNotificationPacket(incoming);
      break;
    case model::packets::PacketType::LE_ADVERTISEMENT:
      if (le_scan_enable_ != bluetooth::hci::OpCode::NONE || le_connect_) {
        IncomingLeAdvertisementPacket(incoming);
@@ -276,6 +279,12 @@ void LinkLayerController::IncomingPacket(
    case model::packets::PacketType::PAGE_REJECT:
      IncomingPageRejectPacket(incoming);
      break;
    case (model::packets::PacketType::PASSKEY):
      IncomingPasskeyPacket(incoming);
      break;
    case (model::packets::PacketType::PASSKEY_FAILED):
      IncomingPasskeyFailedPacket(incoming);
      break;
    case (model::packets::PacketType::REMOTE_NAME_REQUEST):
      IncomingRemoteNameRequest(incoming);
      break;
@@ -943,6 +952,23 @@ void LinkLayerController::IncomingIsoConnectionResponsePacket(
      ft_m_to_s, ft_s_to_m, max_pdu_m_to_s, max_pdu_s_to_m, iso_interval));
}

void LinkLayerController::IncomingKeypressNotificationPacket(
    model::packets::LinkLayerPacketView incoming) {
  auto keypress = model::packets::KeypressNotificationView::Create(incoming);
  ASSERT(keypress.IsValid());
  auto notification_type = keypress.GetNotificationType();
  if (notification_type >
      model::packets::PasskeyNotificationType::ENTRY_COMPLETED) {
    LOG_WARN("Dropping unknown notification type %d",
             static_cast<int>(notification_type));
    return;
  }
  send_event_(bluetooth::hci::KeypressNotificationBuilder::Create(
      incoming.GetSourceAddress(),
      static_cast<bluetooth::hci::KeypressNotificationType>(
          notification_type)));
}

void LinkLayerController::IncomingLeAdvertisementPacket(
    model::packets::LinkLayerPacketView incoming) {
  // TODO: Handle multiple advertisements per packet.
@@ -1269,6 +1295,25 @@ void LinkLayerController::IncomingLeScanResponsePacket(
  }
}

void LinkLayerController::IncomingPasskeyPacket(
    model::packets::LinkLayerPacketView incoming) {
  auto passkey = model::packets::PasskeyView::Create(incoming);
  ASSERT(passkey.IsValid());
  SaveKeyAndAuthenticate('P', incoming.GetSourceAddress());
}

void LinkLayerController::IncomingPasskeyFailedPacket(
    model::packets::LinkLayerPacketView incoming) {
  auto failed = model::packets::PasskeyFailedView::Create(incoming);
  ASSERT(failed.IsValid());
  auto current_peer = incoming.GetSourceAddress();
  security_manager_.AuthenticationRequestFinished();
  ScheduleTask(milliseconds(5), [this, current_peer]() {
    send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
        ErrorCode::AUTHENTICATION_FAILURE, current_peer));
  });
}

void LinkLayerController::IncomingPagePacket(
    model::packets::LinkLayerPacketView incoming) {
  auto page = model::packets::PageView::Create(incoming);
@@ -1440,7 +1485,7 @@ void LinkLayerController::AuthenticateRemoteStage1(const Address& peer,
      break;
    case PairingType::DISPLAY_PIN:
      send_event_(
          bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
          bluetooth::hci::UserPasskeyNotificationBuilder::Create(peer, 123456));
      break;
    case PairingType::DISPLAY_AND_CONFIRM:
      send_event_(
@@ -1580,8 +1625,14 @@ void LinkLayerController::SaveKeyAndAuthenticate(uint8_t key_type,

ErrorCode LinkLayerController::PinCodeRequestReply(const Address& peer,
                                                   std::vector<uint8_t> pin) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  auto current_peer = security_manager_.GetAuthenticationAddress();
  if (peer != current_peer) {
    security_manager_.AuthenticationRequestFinished();
    ScheduleTask(milliseconds(5), [this, current_peer]() {
      send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
          ErrorCode::AUTHENTICATION_FAILURE, current_peer));
    });
    return ErrorCode::UNKNOWN_CONNECTION;
  }
  SaveKeyAndAuthenticate('P', peer);
  return ErrorCode::SUCCESS;
@@ -1589,8 +1640,14 @@ ErrorCode LinkLayerController::PinCodeRequestReply(const Address& peer,

ErrorCode LinkLayerController::PinCodeRequestNegativeReply(
    const Address& peer) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  auto current_peer = security_manager_.GetAuthenticationAddress();
  security_manager_.AuthenticationRequestFinished();
  ScheduleTask(milliseconds(5), [this, current_peer]() {
    send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
        ErrorCode::AUTHENTICATION_FAILURE, current_peer));
  });
  if (peer != current_peer) {
    return ErrorCode::UNKNOWN_CONNECTION;
  }
  return ErrorCode::SUCCESS;
}
@@ -1606,16 +1663,15 @@ ErrorCode LinkLayerController::UserConfirmationRequestReply(

ErrorCode LinkLayerController::UserConfirmationRequestNegativeReply(
    const Address& peer) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  auto current_peer = security_manager_.GetAuthenticationAddress();
  security_manager_.AuthenticationRequestFinished();

  ScheduleTask(milliseconds(5), [this, peer]() {
  ScheduleTask(milliseconds(5), [this, current_peer]() {
    send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
        ErrorCode::AUTHENTICATION_FAILURE, peer));
        ErrorCode::AUTHENTICATION_FAILURE, current_peer));
  });

  if (peer != current_peer) {
    return ErrorCode::UNKNOWN_CONNECTION;
  }
  return ErrorCode::SUCCESS;
}

@@ -1624,7 +1680,8 @@ ErrorCode LinkLayerController::UserPasskeyRequestReply(const Address& peer,
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  LOG_INFO("TODO:Do something with the passkey %06d", numeric_value);
  SendLinkLayerPacket(model::packets::PasskeyBuilder::Create(
      properties_.GetAddress(), peer, numeric_value));
  SaveKeyAndAuthenticate('P', peer);

  return ErrorCode::SUCCESS;
@@ -1632,16 +1689,15 @@ ErrorCode LinkLayerController::UserPasskeyRequestReply(const Address& peer,

ErrorCode LinkLayerController::UserPasskeyRequestNegativeReply(
    const Address& peer) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  auto current_peer = security_manager_.GetAuthenticationAddress();
  security_manager_.AuthenticationRequestFinished();

  ScheduleTask(milliseconds(5), [this, peer]() {
  ScheduleTask(milliseconds(5), [this, current_peer]() {
    send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
        ErrorCode::AUTHENTICATION_FAILURE, peer));
        ErrorCode::AUTHENTICATION_FAILURE, current_peer));
  });

  if (peer != current_peer) {
    return ErrorCode::UNKNOWN_CONNECTION;
  }
  return ErrorCode::SUCCESS;
}

@@ -1659,16 +1715,15 @@ ErrorCode LinkLayerController::RemoteOobDataRequestReply(

ErrorCode LinkLayerController::RemoteOobDataRequestNegativeReply(
    const Address& peer) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  auto current_peer = security_manager_.GetAuthenticationAddress();
  security_manager_.AuthenticationRequestFinished();

  ScheduleTask(milliseconds(5), [this, peer]() {
  ScheduleTask(milliseconds(5), [this, current_peer]() {
    send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
        ErrorCode::AUTHENTICATION_FAILURE, peer));
        ErrorCode::AUTHENTICATION_FAILURE, current_peer));
  });

  if (peer != current_peer) {
    return ErrorCode::UNKNOWN_CONNECTION;
  }
  return ErrorCode::SUCCESS;
}

@@ -1687,6 +1742,20 @@ ErrorCode LinkLayerController::RemoteOobExtendedDataRequestReply(
  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::SendKeypressNotification(
    const Address& peer,
    bluetooth::hci::KeypressNotificationType notification_type) {
  if (notification_type >
      bluetooth::hci::KeypressNotificationType::ENTRY_COMPLETED) {
    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
  }

  SendLinkLayerPacket(model::packets::KeypressNotificationBuilder::Create(
      properties_.GetAddress(), peer,
      static_cast<model::packets::PasskeyNotificationType>(notification_type)));
  return ErrorCode::SUCCESS;
}

void LinkLayerController::HandleAuthenticationRequest(const Address& address,
                                                      uint16_t handle) {
  if (simple_pairing_mode_enabled_ == true) {
+7 −0
Original line number Diff line number Diff line
@@ -75,6 +75,9 @@ class LinkLayerController {
      const std::array<uint8_t, 16>& r_192,
      const std::array<uint8_t, 16>& c_256,
      const std::array<uint8_t, 16>& r_256);
  ErrorCode SendKeypressNotification(
      const Address& peer,
      bluetooth::hci::KeypressNotificationType notification_type);
  void HandleSetConnectionEncryption(const Address& address, uint16_t handle, uint8_t encryption_enable);
  ErrorCode SetConnectionEncryption(uint16_t handle, uint8_t encryption_enable);
  void HandleAuthenticationRequest(const Address& address, uint16_t handle);
@@ -350,6 +353,8 @@ class LinkLayerController {
      model::packets::LinkLayerPacketView packet);
  void IncomingIsoConnectionResponsePacket(
      model::packets::LinkLayerPacketView packet);
  void IncomingKeypressNotificationPacket(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeAdvertisementPacket(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeConnectPacket(model::packets::LinkLayerPacketView packet);
@@ -363,6 +368,8 @@ class LinkLayerController {
  void IncomingPagePacket(model::packets::LinkLayerPacketView packet);
  void IncomingPageRejectPacket(model::packets::LinkLayerPacketView packet);
  void IncomingPageResponsePacket(model::packets::LinkLayerPacketView packet);
  void IncomingPasskeyPacket(model::packets::LinkLayerPacketView packet);
  void IncomingPasskeyFailedPacket(model::packets::LinkLayerPacketView packet);
  void IncomingReadRemoteLmpFeatures(
      model::packets::LinkLayerPacketView packet);
  void IncomingReadRemoteLmpFeaturesResponse(
+5 −6
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ PairingType SecurityManager::GetSimplePairingType() {
          return PairingType::INPUT_PIN;
        case IoCapabilityType::NO_INPUT_NO_OUTPUT:
          return PairingType::AUTO_CONFIRMATION;
        default:
        case IoCapabilityType::INVALID:
          return PairingType::INVALID;
      }
    case IoCapabilityType::DISPLAY_YES_NO:
@@ -163,28 +163,27 @@ PairingType SecurityManager::GetSimplePairingType() {
        case IoCapabilityType::DISPLAY_YES_NO:
          return PairingType::DISPLAY_AND_CONFIRM;
        case IoCapabilityType::KEYBOARD_ONLY:
          return PairingType::DISPLAY_PIN;
          return PairingType::INPUT_PIN;
        case IoCapabilityType::NO_INPUT_NO_OUTPUT:
          return PairingType::AUTO_CONFIRMATION;
        default:
        case IoCapabilityType::INVALID:
          return PairingType::INVALID;
      }
    case IoCapabilityType::KEYBOARD_ONLY:
      switch (host_io_capability_) {
        case IoCapabilityType::DISPLAY_ONLY:
          return PairingType::DISPLAY_PIN;
        case IoCapabilityType::DISPLAY_YES_NO:
          return PairingType::DISPLAY_PIN;
        case IoCapabilityType::KEYBOARD_ONLY:
          return PairingType::INPUT_PIN;
        case IoCapabilityType::NO_INPUT_NO_OUTPUT:
          return PairingType::AUTO_CONFIRMATION;
        default:
        case IoCapabilityType::INVALID:
          return PairingType::INVALID;
      }
    case IoCapabilityType::NO_INPUT_NO_OUTPUT:
      return PairingType::AUTO_CONFIRMATION;
    default:
    case IoCapabilityType::INVALID:
      return PairingType::INVALID;
  }
}
Loading