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

Commit 6a221619 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Gerrit Code Review
Browse files

Merge "Pass locally generated keys around"

parents 9f4c65da d079ff94
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