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

Commit a3bfa06c authored by Myles Watson's avatar Myles Watson Committed by Martin Brabham
Browse files

RootCanal: Support OOB Data

Bug: 162984360
Tag: #gd-refactor
Test: ./cert/run --host SecurityTest
Change-Id: Ieb45321550b2281ec5bece9cde87a75a409beb0a
parent 32b991eb
Loading
Loading
Loading
Loading
+79 −9
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ DualModeController::DualModeController(const std::string& properties_filename, u

#define SET_HANDLER(opcode, method)                                \
  active_hci_commands_[opcode] = [this](CommandPacketView param) { \
    method(param);                                                 \
    method(std::move(param));                                      \
  };
  SET_HANDLER(OpCode::RESET, Reset);
  SET_HANDLER(OpCode::READ_BUFFER_SIZE, ReadBufferSize);
@@ -120,10 +120,23 @@ DualModeController::DualModeController(const std::string& properties_filename, u
              UserConfirmationRequestReply);
  SET_HANDLER(OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY,
              UserConfirmationRequestNegativeReply);
  SET_HANDLER(OpCode::USER_PASSKEY_REQUEST_REPLY, UserPasskeyRequestReply);
  SET_HANDLER(OpCode::USER_PASSKEY_REQUEST_NEGATIVE_REPLY,
              UserPasskeyRequestNegativeReply);
  SET_HANDLER(OpCode::PIN_CODE_REQUEST_REPLY, PinCodeRequestReply);
  SET_HANDLER(OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY,
              PinCodeRequestNegativeReply);
  SET_HANDLER(OpCode::REMOTE_OOB_DATA_REQUEST_REPLY, RemoteOobDataRequestReply);
  SET_HANDLER(OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY,
              RemoteOobDataRequestNegativeReply);
  SET_HANDLER(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY,
              IoCapabilityRequestNegativeReply);
  SET_HANDLER(OpCode::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY,
              RemoteOobExtendedDataRequestReply);
  SET_HANDLER(OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL,
              ReadInquiryResponseTransmitPowerLevel);
  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);
  SET_HANDLER(OpCode::WRITE_LE_HOST_SUPPORT, WriteLeHostSupport);
  SET_HANDLER(OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
@@ -659,6 +672,39 @@ void DualModeController::UserConfirmationRequestNegativeReply(
  send_event_(std::move(packet));
}

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

  Address peer = command_view.GetBdAddr();
  uint8_t pin_length = command_view.GetPinCodeLength();
  std::array<uint8_t, 16> pin = command_view.GetPinCode();
  ErrorCode status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
  if (pin_length >= 1 && pin_length <= 0x10) {
    status = link_layer_controller_.PinCodeRequestReply(
        peer, std::vector<uint8_t>(pin.begin(), pin.begin() + pin_length));
  }

  send_event_(bluetooth::hci::PinCodeRequestReplyCompleteBuilder::Create(
      kNumCommandPackets, status, peer));
}

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

  Address peer = command_view.GetBdAddr();

  auto status = link_layer_controller_.PinCodeRequestNegativeReply(peer);
  auto packet =
      bluetooth::hci::PinCodeRequestNegativeReplyCompleteBuilder::Create(
          kNumCommandPackets, status, peer);

  send_event_(std::move(packet));
}
void DualModeController::UserPasskeyRequestReply(CommandPacketView command) {
  auto command_view = gd_hci::UserPasskeyRequestReplyView::Create(
      gd_hci::SecurityCommandView::Create(command));
@@ -697,17 +743,12 @@ void DualModeController::RemoteOobDataRequestReply(CommandPacketView command) {
  ASSERT(command_view.IsValid());

  Address peer = command_view.GetBdAddr();
  std::array<uint8_t, 16> c = command_view.GetC();
  std::array<uint8_t, 16> r = command_view.GetR();

  auto status = link_layer_controller_.RemoteOobDataRequestReply(
      peer, std::vector<uint8_t>(c.begin(), c.end()),
      std::vector<uint8_t>(r.begin(), r.end()));
  auto packet =
      bluetooth::hci::RemoteOobDataRequestReplyCompleteBuilder::Create(
          kNumCommandPackets, status, peer);
      peer, command_view.GetC(), command_view.GetR());

  send_event_(std::move(packet));
  send_event_(bluetooth::hci::RemoteOobDataRequestReplyCompleteBuilder::Create(
      kNumCommandPackets, status, peer));
}

void DualModeController::RemoteOobDataRequestNegativeReply(
@@ -744,6 +785,23 @@ void DualModeController::IoCapabilityRequestNegativeReply(
  send_event_(std::move(packet));
}

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

  Address peer = command_view.GetBdAddr();

  auto status = link_layer_controller_.RemoteOobExtendedDataRequestReply(
      peer, command_view.GetC192(), command_view.GetR192(),
      command_view.GetC256(), command_view.GetR256());

  send_event_(
      bluetooth::hci::RemoteOobExtendedDataRequestReplyCompleteBuilder::Create(
          kNumCommandPackets, status, peer));
}

void DualModeController::ReadInquiryResponseTransmitPowerLevel(
    CommandPacketView command) {
  auto command_view = gd_hci::ReadInquiryResponseTransmitPowerLevelView::Create(
@@ -757,6 +815,18 @@ void DualModeController::ReadInquiryResponseTransmitPowerLevel(
  send_event_(std::move(packet));
}

void DualModeController::ReadLocalOobData(CommandPacketView command) {
  auto command_view = gd_hci::ReadLocalOobDataView::Create(
      gd_hci::SecurityCommandView::Create(command));
  link_layer_controller_.ReadLocalOobData();
}

void DualModeController::ReadLocalOobExtendedData(CommandPacketView command) {
  auto command_view = gd_hci::ReadLocalOobExtendedDataView::Create(
      gd_hci::SecurityCommandView::Create(command));
  link_layer_controller_.ReadLocalOobExtendedData();
}

void DualModeController::WriteSimplePairingMode(CommandPacketView command) {
  auto command_view = gd_hci::WriteSimplePairingModeView::Create(
      gd_hci::SecurityCommandView::Create(command));
+15 −0
Original line number Diff line number Diff line
@@ -133,6 +133,12 @@ class DualModeController : public Device {
  // 7.1.11
  void LinkKeyRequestNegativeReply(CommandPacketView args);

  // 7.1.12
  void PinCodeRequestReply(CommandPacketView args);

  // 7.1.13
  void PinCodeRequestNegativeReply(CommandPacketView args);

  // 7.1.14
  void ChangeConnectionPacketType(CommandPacketView args);

@@ -190,6 +196,9 @@ class DualModeController : public Device {
  // 7.1.36
  void IoCapabilityRequestNegativeReply(CommandPacketView args);

  // 7.1.53
  void RemoteOobExtendedDataRequestReply(CommandPacketView args);

  // Link Policy Commands
  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.2

@@ -319,6 +328,9 @@ class DualModeController : public Device {
  // 7.3.59
  void WriteSimplePairingMode(CommandPacketView args);

  // 7.3.60
  void ReadLocalOobData(CommandPacketView args);

  // 7.3.61
  void ReadInquiryResponseTransmitPowerLevel(CommandPacketView args);

@@ -328,6 +340,9 @@ class DualModeController : public Device {
  // 7.3.92
  void WriteSecureConnectionsHostSupport(CommandPacketView args);

  // 7.3.95
  void ReadLocalOobExtendedData(CommandPacketView args);

  // Informational Parameters Commands
  // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4

+127 −10
Original line number Diff line number Diff line
@@ -1437,6 +1437,10 @@ void LinkLayerController::AuthenticateRemoteStage1(const Address& peer,
    case PairingType::INPUT_PIN:
      send_event_(bluetooth::hci::UserPasskeyRequestBuilder::Create(peer));
      break;
    case PairingType::OUT_OF_BAND:
      LOG_INFO("Oob data request for %s", peer.ToString().c_str());
      send_event_(bluetooth::hci::RemoteOobDataRequestBuilder::Create(peer));
      break;
    default:
      LOG_ALWAYS_FATAL("Invalid PairingType %d",
                       static_cast<int>(pairing_type));
@@ -1521,14 +1525,25 @@ ErrorCode LinkLayerController::IoCapabilityRequestNegativeReply(
  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::UserConfirmationRequestReply(
void LinkLayerController::SaveKeyAndAuthenticate(uint8_t key_type,
                                                 const Address& peer) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  // TODO: Key could be calculated here.
  std::array<uint8_t, 16> key_vec{1, 2,  3,  4,  5,  6,  7,  8,
                                  9, 10, 11, 12, 13, 14, 15, 16};
  std::array<uint8_t, 16> key_vec{'k',
                                  'e',
                                  'y',
                                  ' ',
                                  'U',
                                  5,
                                  6,
                                  7,
                                  8,
                                  9,
                                  10,
                                  11,
                                  12,
                                  13,
                                  static_cast<uint8_t>(key_id_ >> 8u),
                                  static_cast<uint8_t>(key_id_)};
  key_id_ += 1;
  security_manager_.WriteKey(peer, key_vec);

  security_manager_.AuthenticationRequestFinished();
@@ -1545,6 +1560,31 @@ ErrorCode LinkLayerController::UserConfirmationRequestReply(

  ScheduleTask(milliseconds(15),
               [this, peer]() { AuthenticateRemoteStage2(peer); });
}

ErrorCode LinkLayerController::PinCodeRequestReply(const Address& peer,
                                                   std::vector<uint8_t> pin) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  SaveKeyAndAuthenticate('P', peer);
  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::PinCodeRequestNegativeReply(
    const Address& peer) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::UserConfirmationRequestReply(
    const Address& peer) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  SaveKeyAndAuthenticate('U', peer);
  return ErrorCode::SUCCESS;
}

@@ -1553,6 +1593,7 @@ ErrorCode LinkLayerController::UserConfirmationRequestNegativeReply(
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  security_manager_.AuthenticationRequestFinished();

  ScheduleTask(milliseconds(5), [this, peer]() {
    send_event_(bluetooth::hci::SimplePairingCompleteBuilder::Create(
@@ -1568,6 +1609,8 @@ ErrorCode LinkLayerController::UserPasskeyRequestReply(const Address& peer,
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  LOG_INFO("TODO:Do something with the passkey %06d", numeric_value);
  SaveKeyAndAuthenticate('P', peer);

  return ErrorCode::SUCCESS;
}

@@ -1576,16 +1619,25 @@ ErrorCode LinkLayerController::UserPasskeyRequestNegativeReply(
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  security_manager_.AuthenticationRequestFinished();

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

  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::RemoteOobDataRequestReply(
    const Address& peer, const std::vector<uint8_t>& c,
    const std::vector<uint8_t>& r) {
    const Address& peer, const std::array<uint8_t, 16>& c,
    const std::array<uint8_t, 16>& r) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  LOG_INFO("TODO:Do something with the OOB data c=%d r=%d", c[0], r[0]);
  SaveKeyAndAuthenticate('o', peer);

  return ErrorCode::SUCCESS;
}

@@ -1594,6 +1646,28 @@ ErrorCode LinkLayerController::RemoteOobDataRequestNegativeReply(
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  security_manager_.AuthenticationRequestFinished();

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

  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::RemoteOobExtendedDataRequestReply(
    const Address& peer, const std::array<uint8_t, 16>& c192,
    const std::array<uint8_t, 16>& r192, const std::array<uint8_t, 16>& c256,
    const std::array<uint8_t, 16>& r256) {
  if (security_manager_.GetAuthenticationAddress() != peer) {
    return ErrorCode::AUTHENTICATION_FAILURE;
  }
  LOG_INFO(
      "TODO:Do something with the OOB data c192=%d r192=%d c256=%d r256=%d",
      c192[0], r192[0], c256[0], r256[0]);
  SaveKeyAndAuthenticate('O', peer);

  return ErrorCode::SUCCESS;
}

@@ -1902,6 +1976,49 @@ uint16_t LinkLayerController::ReadDefaultLinkPolicySettings() {
  return default_link_policy_settings_;
}

void LinkLayerController::ReadLocalOobData() {
  std::array<uint8_t, 16> c_array(
      {'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '0', '0', '0', '0', '0', '0',
       static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
       static_cast<uint8_t>(oob_id_ % 0x100)});

  std::array<uint8_t, 16> r_array(
      {'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '0', '0', '0', '0', '0', '0',
       static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
       static_cast<uint8_t>(oob_id_ % 0x100)});

  send_event_(bluetooth::hci::ReadLocalOobDataCompleteBuilder::Create(
      1, ErrorCode::SUCCESS, c_array, r_array));
  oob_id_ += 1;
}

void LinkLayerController::ReadLocalOobExtendedData() {
  std::array<uint8_t, 16> c_192_array(
      {'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '1', '9', '2', '0', '0', '0',
       static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
       static_cast<uint8_t>(oob_id_ % 0x100)});

  std::array<uint8_t, 16> r_192_array(
      {'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '1', '9', '2', '0', '0', '0',
       static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
       static_cast<uint8_t>(oob_id_ % 0x100)});

  std::array<uint8_t, 16> c_256_array(
      {'c', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '2', '5', '6', '0', '0', '0',
       static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
       static_cast<uint8_t>(oob_id_ % 0x100)});

  std::array<uint8_t, 16> r_256_array(
      {'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', '2', '5', '6', '0', '0', '0',
       static_cast<uint8_t>((oob_id_ % 0x10000) >> 8u),
       static_cast<uint8_t>(oob_id_ % 0x100)});

  send_event_(bluetooth::hci::ReadLocalOobExtendedDataCompleteBuilder::Create(
      1, ErrorCode::SUCCESS, c_192_array, r_192_array, c_256_array,
      r_256_array));
  oob_id_ += 1;
}

ErrorCode LinkLayerController::FlowSpecification(
    uint16_t handle, uint8_t flow_direction, uint8_t service_type,
    uint32_t /* token_rate */, uint32_t /* token_bucket_size */,
+16 −2
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ class LinkLayerController {
  void StartSimplePairing(const Address& address);
  void AuthenticateRemoteStage1(const Address& address, PairingType pairing_type);
  void AuthenticateRemoteStage2(const Address& address);
  void SaveKeyAndAuthenticate(uint8_t key_type, const Address& peer);
  ErrorCode LinkKeyRequestReply(const Address& address,
                                const std::array<uint8_t, 16>& key);
  ErrorCode LinkKeyRequestNegativeReply(const Address& address);
@@ -58,15 +59,22 @@ class LinkLayerController {
                                     uint8_t authentication_requirements);
  ErrorCode IoCapabilityRequestNegativeReply(const Address& peer,
                                             ErrorCode reason);
  ErrorCode PinCodeRequestReply(const Address& peer, std::vector<uint8_t> pin);
  ErrorCode PinCodeRequestNegativeReply(const Address& peer);
  ErrorCode UserConfirmationRequestReply(const Address& peer);
  ErrorCode UserConfirmationRequestNegativeReply(const Address& peer);
  ErrorCode UserPasskeyRequestReply(const Address& peer,
                                    uint32_t numeric_value);
  ErrorCode UserPasskeyRequestNegativeReply(const Address& peer);
  ErrorCode RemoteOobDataRequestReply(const Address& peer,
                                      const std::vector<uint8_t>& c,
                                      const std::vector<uint8_t>& r);
                                      const std::array<uint8_t, 16>& c,
                                      const std::array<uint8_t, 16>& r);
  ErrorCode RemoteOobDataRequestNegativeReply(const Address& peer);
  ErrorCode RemoteOobExtendedDataRequestReply(
      const Address& peer, const std::array<uint8_t, 16>& c_192,
      const std::array<uint8_t, 16>& r_192,
      const std::array<uint8_t, 16>& c_256,
      const std::array<uint8_t, 16>& r_256);
  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);
@@ -313,6 +321,9 @@ class LinkLayerController {
  ErrorCode WriteDefaultLinkPolicySettings(uint16_t settings);
  uint16_t ReadDefaultLinkPolicySettings();

  void ReadLocalOobData();
  void ReadLocalOobExtendedData();

  void HandleIso(bluetooth::hci::IsoPacketView iso);

 protected:
@@ -405,6 +416,9 @@ class LinkLayerController {
                     Phy::Type phy_type)>
      send_to_remote_;

  uint32_t oob_id_ = 1;
  uint32_t key_id_ = 1;

  // LE state
  std::vector<uint8_t> le_event_mask_;

+11 −3
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ void SecurityManager::SetPeerIoCapability(const Address& addr, uint8_t io_capabi
    peer_io_capability_ = IoCapabilityType::INVALID;
    peer_capabilities_valid_ = false;
  }
  peer_oob_present_flag_ = (oob_present_flag == 1);
  peer_oob_present_flag_ = oob_present_flag;
  if (authentication_requirements <= static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM)) {
    peer_authentication_requirements_ = static_cast<AuthenticationType>(authentication_requirements);
  } else {
@@ -105,11 +105,12 @@ void SecurityManager::SetLocalIoCapability(const Address& peer, uint8_t io_capab
  ASSERT(peer == peer_address_);
  ASSERT_LOG(io_capability <= static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT), "io_capability = %d",
             static_cast<int>(io_capability));
  ASSERT_LOG(oob_present_flag <= 1, "oob_present_flag = %hhx ", oob_present_flag);
  ASSERT_LOG(oob_present_flag <= 3, "oob_present_flag = %hhx ",
             oob_present_flag);
  ASSERT_LOG(authentication_requirements <= static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM),
             "authentication_requirements = %d", static_cast<int>(authentication_requirements));
  host_io_capability_ = static_cast<IoCapabilityType>(io_capability);
  host_oob_present_flag_ = (oob_present_flag == 1);
  host_oob_present_flag_ = oob_present_flag;
  host_authentication_requirements_ = static_cast<AuthenticationType>(authentication_requirements);
  host_capabilities_valid_ = true;
}
@@ -132,6 +133,13 @@ PairingType SecurityManager::GetSimplePairingType() {
  if (!(peer_requires_mitm || host_requires_mitm)) {
    return PairingType::AUTO_CONFIRMATION;
  }
  if (peer_oob_present_flag_ != 0 || host_oob_present_flag_ != 0) {
    if (peer_oob_present_flag_ != host_oob_present_flag_) {
      return PairingType::INVALID;
    } else {
      return PairingType::OUT_OF_BAND;
    }
  }
  LOG_INFO("%s: host does%s require peer does%s require MITM",
           peer_address_.ToString().c_str(), host_requires_mitm ? "" : "n't",
           peer_requires_mitm ? "" : "n't");
Loading