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 Original line Diff line number Diff line
@@ -39,15 +39,18 @@ namespace security {


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

  std::optional<crypto_toolbox::Octet16> remote_link_key; /* BR/EDR Keys */
  /* BR/EDR Keys */

  std::optional<crypto_toolbox::Octet16> link_key;
  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 */
/* This class represents the result of pairing, as returned from Pairing Handler */
+10 −9
Original line number Original line 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.
  // TODO: ensure that the security level is not weaker than what we already have.
  auto record = this->security_database_.FindOrCreate(result.connection_address);
  auto record = this->security_database_.FindOrCreate(result.connection_address);
  record->identity_address_ = result.distributed_keys.identity_address;
  record->identity_address_ = result.distributed_keys.remote_identity_address;
  record->ltk = result.distributed_keys.ltk;
  record->remote_ltk = result.distributed_keys.remote_ltk;
  record->key_size = result.key_size;
  record->key_size = result.key_size;
  record->security_level = result.security_level;
  record->security_level = result.security_level;
  record->ediv = result.distributed_keys.ediv;
  record->remote_ediv = result.distributed_keys.remote_ediv;
  record->rand = result.distributed_keys.rand;
  record->remote_rand = result.distributed_keys.remote_rand;
  record->irk = result.distributed_keys.irk;
  record->remote_irk = result.distributed_keys.remote_irk;
  record->signature_key = result.distributed_keys.signature_key;
  record->remote_signature_key = result.distributed_keys.remote_signature_key;
  if (result.distributed_keys.link_key)
  if (result.distributed_keys.remote_link_key)
    record->SetLinkKey(*result.distributed_keys.link_key, hci::KeyType::AUTHENTICATED_P256);
    record->SetLinkKey(*result.distributed_keys.remote_link_key, hci::KeyType::AUTHENTICATED_P256);
  security_database_.SaveRecordsToStorage();
  security_database_.SaveRecordsToStorage();


  NotifyDeviceBonded(result.connection_address);
  NotifyDeviceBonded(result.connection_address);
  // We also notify bond complete using identity address. That's what old stack used to do.
  // 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);
  security_handler_->CallOn(this, &SecurityManagerImpl::WipeLePairingHandler);
}
}
+20 −12
Original line number Original line 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
  // If it's secure connections pairing, do cross-transport key derivation
  DistributedKeys distributed_keys = std::get<DistributedKeys>(keyExchangeStatus);
  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);
    bool use_h7 = (pairing_response.GetAuthReq() & AuthReqMaskCt2);
    Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.ltk), use_h7);
    Octet16 link_key = crypto_toolbox::ltk_to_link_key(*(distributed_keys.remote_ltk), use_h7);
    distributed_keys.link_key = link_key;
    distributed_keys.remote_link_key = link_key;
  }
  }


  // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag;
  // 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);
  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
  // 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};
  Octet16 my_ltk = bluetooth::os::GenerateRandom<16>();
  uint16_t my_ediv{0};
  uint16_t my_ediv = bluetooth::os::GenerateRandom();
  std::array<uint8_t, 8> my_rand = {0};
  std::array<uint8_t, 8> my_rand = bluetooth::os::GenerateRandom<8>();


  Octet16 my_irk = {0x01};
  Octet16 my_irk = {0x01};
  Address my_identity_address;
  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,
    SendKeys(i, keys_i_send, my_ltk, my_ediv, my_rand, my_irk, my_identity_address, my_identity_address_type,
             my_signature_key);
             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");
    LOG_INFO("Key distribution finish");
    return keys;
    return keys;
  } else {
  } else {
@@ -364,6 +368,10 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati
    if (std::holds_alternative<PairingFailure>(keys)) {
    if (std::holds_alternative<PairingFailure>(keys)) {
      return 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");
    LOG_INFO("Key distribution finish");
    return keys;
    return keys;
  }
  }
@@ -433,12 +441,12 @@ DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_rec
    signature_key = std::get<SigningInformationView>(packet).GetSignatureKey();
    signature_key = std::get<SigningInformationView>(packet).GetSignatureKey();
  }
  }


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


void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv,
void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv,
+9 −5
Original line number Original line Diff line number Diff line
@@ -126,13 +126,17 @@ class SecurityRecord {
  /* Identity Address */
  /* Identity Address */
  std::optional<hci::AddressWithType> 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 key_size;
  uint8_t security_level;
  uint8_t security_level;
  std::optional<uint16_t> ediv;
  std::optional<uint16_t> remote_ediv;
  std::optional<std::array<uint8_t, 8>> rand;
  std::optional<std::array<uint8_t, 8>> remote_rand;
  std::optional<crypto_toolbox::Octet16> irk;
  std::optional<crypto_toolbox::Octet16> remote_irk;
  std::optional<crypto_toolbox::Octet16> signature_key;
  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
}  // namespace record
+1 −1
Original line number Original line Diff line number Diff line
@@ -59,7 +59,7 @@ class SecurityRecordDatabase {
      std::shared_ptr<SecurityRecord> record = *it;
      std::shared_ptr<SecurityRecord> record = *it;
      if (record->identity_address_.has_value() && record->identity_address_.value() == address) return it;
      if (record->identity_address_.has_value() && record->identity_address_.value() == address) return it;
      if (record->GetPseudoAddress() == 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();
    return records_.end();
  }
  }
Loading