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

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

Merge "Pass locally generated keys around" am: 6a221619 am: 08fc15e0

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

Change-Id: I5bf81a712f4eeecae00e957d15669adb19c4f837
parents ec17a772 08fc15e0
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -39,15 +39,18 @@ namespace security {

struct DistributedKeys {
  /* LE Keys*/
  std::optional<crypto_toolbox::Octet16> ltk;
  std::optional<uint16_t> ediv;
  std::optional<std::array<uint8_t, 8>> rand;
  std::optional<hci::AddressWithType> identity_address;
  std::optional<crypto_toolbox::Octet16> irk;
  std::optional<crypto_toolbox::Octet16> signature_key;

  /* BR/EDR Keys */
  std::optional<crypto_toolbox::Octet16> link_key;
  std::optional<crypto_toolbox::Octet16> remote_ltk;
  std::optional<uint16_t> remote_ediv;
  std::optional<std::array<uint8_t, 8>> remote_rand;
  std::optional<hci::AddressWithType> remote_identity_address;
  std::optional<crypto_toolbox::Octet16> remote_irk;
  std::optional<crypto_toolbox::Octet16> remote_signature_key;
  std::optional<crypto_toolbox::Octet16> remote_link_key; /* BR/EDR Keys */

  std::optional<crypto_toolbox::Octet16> local_ltk;
  std::optional<uint16_t> local_ediv;
  std::optional<std::array<uint8_t, 8>> local_rand;
  std::optional<crypto_toolbox::Octet16> local_signature_key;
};

/* This class represents the result of pairing, as returned from Pairing Handler */
+10 −9
Original line number Diff line number Diff line
@@ -662,21 +662,22 @@ void SecurityManagerImpl::OnPairingFinished(security::PairingResultOrFailure pai

  // TODO: ensure that the security level is not weaker than what we already have.
  auto record = this->security_database_.FindOrCreate(result.connection_address);
  record->identity_address_ = result.distributed_keys.identity_address;
  record->ltk = result.distributed_keys.ltk;
  record->identity_address_ = result.distributed_keys.remote_identity_address;
  record->remote_ltk = result.distributed_keys.remote_ltk;
  record->key_size = result.key_size;
  record->security_level = result.security_level;
  record->ediv = result.distributed_keys.ediv;
  record->rand = result.distributed_keys.rand;
  record->irk = result.distributed_keys.irk;
  record->signature_key = result.distributed_keys.signature_key;
  if (result.distributed_keys.link_key)
    record->SetLinkKey(*result.distributed_keys.link_key, hci::KeyType::AUTHENTICATED_P256);
  record->remote_ediv = result.distributed_keys.remote_ediv;
  record->remote_rand = result.distributed_keys.remote_rand;
  record->remote_irk = result.distributed_keys.remote_irk;
  record->remote_signature_key = result.distributed_keys.remote_signature_key;
  if (result.distributed_keys.remote_link_key)
    record->SetLinkKey(*result.distributed_keys.remote_link_key, hci::KeyType::AUTHENTICATED_P256);
  security_database_.SaveRecordsToStorage();

  NotifyDeviceBonded(result.connection_address);
  // We also notify bond complete using identity address. That's what old stack used to do.
  if (result.distributed_keys.identity_address) NotifyDeviceBonded(*result.distributed_keys.identity_address);
  if (result.distributed_keys.remote_identity_address)
    NotifyDeviceBonded(*result.distributed_keys.remote_identity_address);

  security_handler_->CallOn(this, &SecurityManagerImpl::WipeLePairingHandler);
}
+20 −12
Original line number Diff line number Diff line
@@ -198,10 +198,10 @@ void PairingHandlerLe::PairingMain(InitialInformations i) {

  // If it's secure connections pairing, do cross-transport key derivation
  DistributedKeys distributed_keys = std::get<DistributedKeys>(keyExchangeStatus);
  if ((pairing_response.GetAuthReq() & AuthReqMaskSc) && distributed_keys.ltk.has_value()) {
  if ((pairing_response.GetAuthReq() & AuthReqMaskSc) && distributed_keys.remote_ltk.has_value()) {
    bool use_h7 = (pairing_response.GetAuthReq() & AuthReqMaskCt2);
    Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.ltk), use_h7);
    distributed_keys.link_key = link_key;
    Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.remote_ltk), use_h7);
    distributed_keys.remote_link_key = link_key;
  }

  // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag;
@@ -336,9 +336,9 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati
  LOG_INFO("Key distribution start, keys_i_send=0x%02x, keys_i_receive=0x%02x", keys_i_send, keys_i_receive);

  // TODO: obtain actual values, and apply key_size to the LTK
  Octet16 my_ltk = {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE};
  uint16_t my_ediv{0};
  std::array<uint8_t, 8> my_rand = {0};
  Octet16 my_ltk = bluetooth::os::GenerateRandom<16>();
  uint16_t my_ediv = bluetooth::os::GenerateRandom();
  std::array<uint8_t, 8> my_rand = bluetooth::os::GenerateRandom<8>();

  Octet16 my_irk = {0x01};
  Address my_identity_address;
@@ -354,6 +354,10 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati

    SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type,
             my_signature_key);

    std::get<DistributedKeys>(keys).local_ltk = my_ltk;
    std::get<DistributedKeys>(keys).local_ediv = my_ediv;
    std::get<DistributedKeys>(keys).local_rand = my_rand;
    LOG_INFO("Key distribution finish");
    return keys;
  } else {
@@ -364,6 +368,10 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati
    if (std::holds_alternative<PairingFailure>(keys)) {
      return keys;
    }

    std::get<DistributedKeys>(keys).local_ltk = my_ltk;
    std::get<DistributedKeys>(keys).local_ediv = my_ediv;
    std::get<DistributedKeys>(keys).local_rand = my_rand;
    LOG_INFO("Key distribution finish");
    return keys;
  }
@@ -433,12 +441,12 @@ DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_rec
    signature_key = std::get<SigningInformationView>(packet).GetSignatureKey();
  }

  return DistributedKeys{.ltk = ltk,
                         .ediv = ediv,
                         .rand = rand,
                         .identity_address = identity_address,
                         .irk = irk,
                         .signature_key = signature_key};
  return DistributedKeys{.remote_ltk = ltk,
                         .remote_ediv = ediv,
                         .remote_rand = rand,
                         .remote_identity_address = identity_address,
                         .remote_irk = irk,
                         .remote_signature_key = signature_key};
}

void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv,
+9 −5
Original line number Diff line number Diff line
@@ -126,13 +126,17 @@ class SecurityRecord {
  /* Identity Address */
  std::optional<hci::AddressWithType> identity_address_;

  std::optional<crypto_toolbox::Octet16> ltk;
  std::optional<crypto_toolbox::Octet16> remote_ltk;
  uint8_t key_size;
  uint8_t security_level;
  std::optional<uint16_t> ediv;
  std::optional<std::array<uint8_t, 8>> rand;
  std::optional<crypto_toolbox::Octet16> irk;
  std::optional<crypto_toolbox::Octet16> signature_key;
  std::optional<uint16_t> remote_ediv;
  std::optional<std::array<uint8_t, 8>> remote_rand;
  std::optional<crypto_toolbox::Octet16> remote_irk;
  std::optional<crypto_toolbox::Octet16> remote_signature_key;

  std::optional<crypto_toolbox::Octet16> local_ltk;
  std::optional<uint16_t> local_ediv;
  std::optional<std::array<uint8_t, 8>> local_rand;
};

}  // namespace record
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ class SecurityRecordDatabase {
      std::shared_ptr<SecurityRecord> record = *it;
      if (record->identity_address_.has_value() && record->identity_address_.value() == address) return it;
      if (record->GetPseudoAddress() == address) return it;
      if (record->irk.has_value() && address.IsRpaThatMatchesIrk(record->irk.value())) return it;
      if (record->remote_irk.has_value() && address.IsRpaThatMatchesIrk(record->remote_irk.value())) return it;
    }
    return records_.end();
  }
Loading