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

Commit caf8b568 authored by Myles Watson's avatar Myles Watson
Browse files

RootCanal: Use PIN pairing if no SSP

Bug: 162984360
Tag: #gd-refactor
Test: cert/run --host SecurityTest
Change-Id: Ibfdb69449f760fa67e3020955d584571b153bf35
parent 34965b12
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -683,6 +683,7 @@ void DualModeController::PinCodeRequestReply(CommandPacketView command) {
  auto command_view = gd_hci::PinCodeRequestReplyView::Create(
      gd_hci::SecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());
  LOG_INFO("%s", properties_.GetAddress().ToString().c_str());

  Address peer = command_view.GetBdAddr();
  uint8_t pin_length = command_view.GetPinCodeLength();
@@ -702,6 +703,7 @@ void DualModeController::PinCodeRequestNegativeReply(
  auto command_view = gd_hci::PinCodeRequestNegativeReplyView::Create(
      gd_hci::SecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());
  LOG_INFO("%s", properties_.GetAddress().ToString().c_str());

  Address peer = command_view.GetBdAddr();

@@ -853,8 +855,8 @@ void DualModeController::WriteSimplePairingMode(CommandPacketView command) {
      gd_hci::SecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());

  link_layer_controller_.WriteSimplePairingMode(
      command_view.GetSimplePairingMode() == gd_hci::Enable::ENABLED);
  auto enabled = command_view.GetSimplePairingMode() == gd_hci::Enable::ENABLED;
  properties_.SetSecureSimplePairingSupport(enabled);
  auto packet = bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS);
  send_event_(std::move(packet));
@@ -880,6 +882,9 @@ void DualModeController::ChangeConnectionPacketType(CommandPacketView command) {
void DualModeController::WriteLeHostSupport(CommandPacketView command) {
  auto command_view = gd_hci::WriteLeHostSupportView::Create(command);
  ASSERT(command_view.IsValid());
  auto le_support =
      command_view.GetLeSupportedHost() == gd_hci::Enable::ENABLED;
  properties_.SetLeHostSupport(le_support);
  auto packet = bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS);
  send_event_(std::move(packet));
@@ -889,7 +894,10 @@ void DualModeController::WriteSecureConnectionsHostSupport(
    CommandPacketView command) {
  auto command_view = gd_hci::WriteSecureConnectionsHostSupportView::Create(
      gd_hci::SecurityCommandView::Create(command));
  properties_.SetExtendedFeatures(properties_.GetExtendedFeatures(1) | 0x8, 1);
  ASSERT(command_view.IsValid());
  properties_.SetSecureConnections(
      command_view.GetSecureConnectionsHostSupport() ==
      bluetooth::hci::Enable::ENABLED);
  auto packet =
      bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS);
+64 −34
Original line number Diff line number Diff line
@@ -710,26 +710,36 @@ void LinkLayerController::IncomingInquiryResponsePacket(

void LinkLayerController::IncomingIoCapabilityRequestPacket(
    model::packets::LinkLayerPacketView incoming) {
  if (!simple_pairing_mode_enabled_) {
    LOG_WARN("Only simple pairing mode is implemented");
  Address peer = incoming.GetSourceAddress();
  uint16_t handle = connections_.GetHandle(AddressWithType(
      peer, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS));
  if (handle == kReservedHandle) {
    LOG_INFO("Device not connected %s", peer.ToString().c_str());
    return;
  }

  if (!properties_.GetSecureSimplePairingSupported()) {
    LOG_WARN("Trying PIN pairing for %s",
             incoming.GetDestinationAddress().ToString().c_str());
    SendLinkLayerPacket(
        model::packets::IoCapabilityNegativeResponseBuilder::Create(
            incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
            static_cast<uint8_t>(
                ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE)));
    security_manager_.AuthenticationRequest(incoming.GetSourceAddress(),
                                            handle);
    send_event_(bluetooth::hci::PinCodeRequestBuilder::Create(
        incoming.GetSourceAddress()));
    return;
  }

  auto request = model::packets::IoCapabilityRequestView::Create(incoming);
  ASSERT(request.IsValid());

  Address peer = incoming.GetSourceAddress();
  uint8_t io_capability = request.GetIoCapability();
  uint8_t oob_data_present = request.GetOobDataPresent();
  uint8_t authentication_requirements = request.GetAuthenticationRequirements();

  uint16_t handle = connections_.GetHandle(AddressWithType(
      peer, bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS));
  if (handle == kReservedHandle) {
    LOG_INFO("Device not connected %s", peer.ToString().c_str());
    return;
  }

  auto packet = bluetooth::hci::IoCapabilityResponseBuilder::Create(
      peer, static_cast<bluetooth::hci::IoCapability>(io_capability),
      static_cast<bluetooth::hci::OobDataPresent>(oob_data_present),
@@ -761,6 +771,15 @@ void LinkLayerController::IncomingIoCapabilityResponsePacket(
    model::packets::LinkLayerPacketView incoming) {
  auto response = model::packets::IoCapabilityResponseView::Create(incoming);
  ASSERT(response.IsValid());
  if (!properties_.GetSecureSimplePairingSupported()) {
    LOG_WARN("Only simple pairing mode is implemented");
    SendLinkLayerPacket(
        model::packets::IoCapabilityNegativeResponseBuilder::Create(
            incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
            static_cast<uint8_t>(
                ErrorCode::UNSUPPORTED_REMOTE_OR_LMP_FEATURE)));
    return;
  }

  Address peer = incoming.GetSourceAddress();
  uint8_t io_capability = response.GetIoCapability();
@@ -795,6 +814,10 @@ void LinkLayerController::IncomingIoCapabilityNegativeResponsePacket(
  ASSERT(security_manager_.GetAuthenticationAddress() == peer);

  security_manager_.InvalidateIoCapabilities();
  LOG_INFO("%s doesn't support SSP, try PIN",
           incoming.GetSourceAddress().ToString().c_str());
  send_event_(bluetooth::hci::PinCodeRequestBuilder::Create(
      incoming.GetSourceAddress()));
}

void LinkLayerController::IncomingIsoPacket(LinkLayerPacketView incoming) {
@@ -1454,11 +1477,6 @@ void LinkLayerController::RegisterTaskCancel(
  cancel_task_ = task_cancel;
}

void LinkLayerController::WriteSimplePairingMode(bool enabled) {
  ASSERT_LOG(enabled, "The spec says don't disable this!");
  simple_pairing_mode_enabled_ = enabled;
}

void LinkLayerController::StartSimplePairing(const Address& address) {
  // IO Capability Exchange (See the Diagram in the Spec)
  auto packet = bluetooth::hci::IoCapabilityRequestBuilder::Create(address);
@@ -1538,10 +1556,17 @@ ErrorCode LinkLayerController::LinkKeyRequestNegativeReply(
    return ErrorCode::UNKNOWN_CONNECTION;
  }

  if (properties_.GetSecureSimplePairingSupported()) {
    security_manager_.AuthenticationRequest(address, handle);

    ScheduleTask(milliseconds(5),
                 [this, address]() { StartSimplePairing(address); });
  } else {
    LOG_INFO("PIN pairing %s", properties_.GetAddress().ToString().c_str());
    ScheduleTask(milliseconds(5), [this, address]() {
      send_event_(bluetooth::hci::PinCodeRequestBuilder::Create(address));
    });
  }
  return ErrorCode::SUCCESS;
}

@@ -1609,6 +1634,13 @@ void LinkLayerController::SaveKeyAndAuthenticate(uint8_t key_type,

  security_manager_.AuthenticationRequestFinished();

  if (key_type == 'L') {
    // Legacy
    ScheduleTask(milliseconds(5), [this, peer, key_vec]() {
      send_event_(bluetooth::hci::LinkKeyNotificationBuilder::Create(
          peer, key_vec, bluetooth::hci::KeyType::AUTHENTICATED_P192));
    });
  } else {
    ScheduleTask(milliseconds(5), [this, peer]() {
      send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
          ErrorCode::SUCCESS, peer));
@@ -1618,6 +1650,7 @@ void LinkLayerController::SaveKeyAndAuthenticate(uint8_t key_type,
      send_event_(bluetooth::hci::LinkKeyNotificationBuilder::Create(
          peer, key_vec, bluetooth::hci::KeyType::AUTHENTICATED_P256));
    });
  }

  ScheduleTask(milliseconds(15),
               [this, peer]() { AuthenticateRemoteStage2(peer); });
@@ -1625,8 +1658,11 @@ void LinkLayerController::SaveKeyAndAuthenticate(uint8_t key_type,

ErrorCode LinkLayerController::PinCodeRequestReply(const Address& peer,
                                                   std::vector<uint8_t> pin) {
  LOG_INFO("%s", properties_.GetAddress().ToString().c_str());
  auto current_peer = security_manager_.GetAuthenticationAddress();
  if (peer != current_peer) {
    LOG_INFO("%s: %s != %s", properties_.GetAddress().ToString().c_str(),
             peer.ToString().c_str(), current_peer.ToString().c_str());
    security_manager_.AuthenticationRequestFinished();
    ScheduleTask(milliseconds(5), [this, current_peer]() {
      send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
@@ -1634,7 +1670,8 @@ ErrorCode LinkLayerController::PinCodeRequestReply(const Address& peer,
    });
    return ErrorCode::UNKNOWN_CONNECTION;
  }
  SaveKeyAndAuthenticate('P', peer);
  LOG_INFO("Authenticating %s", peer.ToString().c_str());
  SaveKeyAndAuthenticate('L', peer);  // Legacy
  return ErrorCode::SUCCESS;
}

@@ -1758,16 +1795,9 @@ ErrorCode LinkLayerController::SendKeypressNotification(

void LinkLayerController::HandleAuthenticationRequest(const Address& address,
                                                      uint16_t handle) {
  if (simple_pairing_mode_enabled_ == true) {
    security_manager_.AuthenticationRequest(address, handle);
    auto packet = bluetooth::hci::LinkKeyRequestBuilder::Create(address);
    send_event_(std::move(packet));
  } else {  // Should never happen for our phones
    // Check for a key, try to authenticate, ask for a PIN.
    auto packet = bluetooth::hci::AuthenticationCompleteBuilder::Create(
        ErrorCode::AUTHENTICATION_FAILURE, handle);
    send_event_(std::move(packet));
  }
}

ErrorCode LinkLayerController::AuthenticationRequested(uint16_t handle) {
+0 −3
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ class LinkLayerController {
  ErrorCode SendScoToRemote(bluetooth::hci::ScoPacketView sco_packet);
  ErrorCode SendAclToRemote(bluetooth::hci::AclPacketView acl_packet);

  void WriteSimplePairingMode(bool enabled);
  void StartSimplePairing(const Address& address);
  void AuthenticateRemoteStage1(const Address& address, PairingType pairing_type);
  void AuthenticateRemoteStage2(const Address& address);
@@ -469,8 +468,6 @@ class LinkLayerController {

  bool page_scans_enabled_{false};
  bool inquiry_scans_enabled_{false};

  bool simple_pairing_mode_enabled_{false};
};

}  // namespace test_vendor_lib
+30 −1
Original line number Diff line number Diff line
@@ -55,6 +55,35 @@ class DeviceProperties {
    extended_features_[page_number] = features;
  }

  bool GetSecureSimplePairingSupported() const {
    uint64_t ssp_bit = 0x1;
    return extended_features_[1] & ssp_bit;
  }

  void SetSecureSimplePairingSupport(bool supported) {
    uint64_t ssp_bit = 0x1;
    extended_features_[1] &= ~ssp_bit;
    if (supported) {
      extended_features_[1] = extended_features_[1] | ssp_bit;
    }
  }

  void SetLeHostSupport(bool le_supported) {
    uint64_t le_bit = 0x2;
    extended_features_[1] &= ~le_bit;
    if (le_supported) {
      extended_features_[1] = extended_features_[1] | le_bit;
    }
  }

  void SetSecureConnections(bool supported) {
    uint64_t secure_bit = 0x8;
    extended_features_[1] &= ~secure_bit;
    if (supported) {
      extended_features_[1] = extended_features_[1] | secure_bit;
    }
  }

  // Specification Version 4.2, Volume 2, Part E, Section 7.4.4
  uint8_t GetExtendedFeaturesMaximumPageNumber() const {
    return extended_features_.size() - 1;
@@ -325,7 +354,7 @@ class DeviceProperties {
  std::vector<uint8_t> supported_codecs_;
  std::vector<uint32_t> vendor_specific_codecs_;
  std::vector<uint8_t> supported_commands_;
  std::vector<uint64_t> extended_features_{{0x875b3fd8fe8ffeff, 0x0f}};
  std::vector<uint64_t> extended_features_{{0x875b3fd8fe8ffeff, 0x04}};
  ClassOfDevice class_of_device_{{0, 0, 0}};
  std::vector<uint8_t> extended_inquiry_data_;
  std::array<uint8_t, 248> name_{};