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

Commit 4fd7be86 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Security: Cross-transport key derivation for Pairing initiated over LE

Bug: 139138118
Change-Id: I8ebbf88206ad87a275cf291c5e649f28fc35a54e
parent 5005e8a4
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -37,11 +37,18 @@
namespace bluetooth {
namespace security {

using DistributedKeys =
    std::tuple<std::optional<crypto_toolbox::Octet16> /* ltk */, std::optional<uint16_t> /*ediv*/,
               std::optional<std::array<uint8_t, 8>> /* rand */, std::optional<Address> /* Identity address */,
               AddrType, std::optional<crypto_toolbox::Octet16> /* IRK */,
               std::optional<crypto_toolbox::Octet16>> /* Signature Key */;
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;
};

/* This class represents the result of pairing, as returned from Pairing Handler */
struct PairingResult {
+19 −5
Original line number Diff line number Diff line
@@ -161,6 +161,14 @@ void PairingHandlerLe::PairingMain(InitialInformations i) {
    return;
  }

  // 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()) {
    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;
  }

  // bool bonding = pairing_request.GetAuthReq() & pairing_response.GetAuthReq() & AuthReqMaskBondingFlag;

  i.OnPairingFinished(PairingResult{
@@ -323,8 +331,7 @@ DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_rec
  std::optional<Octet16> ltk;                 /* Legacy only */
  std::optional<uint16_t> ediv;               /* Legacy only */
  std::optional<std::array<uint8_t, 8>> rand; /* Legacy only */
  std::optional<Address> identity_address;
  AddrType identity_address_type;
  std::optional<hci::AddressWithType> identity_address;
  std::optional<Octet16> irk;
  std::optional<Octet16> signature_key;

@@ -367,8 +374,10 @@ DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_rec
      return std::get<PairingFailure>(iapacket);
    }
    LOG_INFO("Received Identity Address Information");
    identity_address = std::get<IdentityAddressInformationView>(iapacket).GetBdAddr();
    identity_address_type = std::get<IdentityAddressInformationView>(iapacket).GetAddrType();
    auto iapacketview = std::get<IdentityAddressInformationView>(iapacket);
    identity_address = hci::AddressWithType(iapacketview.GetBdAddr(), iapacketview.GetAddrType() == AddrType::PUBLIC
                                                                          ? hci::AddressType::PUBLIC_DEVICE_ADDRESS
                                                                          : hci::AddressType::RANDOM_DEVICE_ADDRESS);
  }

  if (keys_i_receive & KeyMaskSign) {
@@ -382,7 +391,12 @@ DistributedKeysOrFailure PairingHandlerLe::ReceiveKeys(const uint8_t& keys_i_rec
    signature_key = std::get<SigningInformationView>(packet).GetSignatureKey();
  }

  return DistributedKeys{ltk, ediv, rand, identity_address, identity_address_type, irk, signature_key};
  return DistributedKeys{.ltk = ltk,
                         .ediv = ediv,
                         .rand = rand,
                         .identity_address = identity_address,
                         .irk = irk,
                         .signature_key = signature_key};
}

void PairingHandlerLe::SendKeys(const InitialInformations& i, const uint8_t& keys_i_send, Octet16 ltk, uint16_t ediv,