Merge "RootCanal: Enable ASan and UBSan and clang-tidy on root-canal"
diff --git a/gd/security/initial_informations.h b/gd/security/initial_informations.h
index 5721931..56a6bce 100644
--- a/gd/security/initial_informations.h
+++ b/gd/security/initial_informations.h
@@ -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 {
diff --git a/gd/security/pairing_handler_le.cc b/gd/security/pairing_handler_le.cc
index 15acea9..4e18349 100644
--- a/gd/security/pairing_handler_le.cc
+++ b/gd/security/pairing_handler_le.cc
@@ -161,6 +161,14 @@
     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 @@
   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 @@
       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 @@
     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,