OSDN Git Service

GD Security Pass local IRK and Address around
authorJakub Pawlowski <jpawlowski@google.com>
Wed, 21 Oct 2020 21:11:50 +0000 (23:11 +0200)
committerJakub Pawlowski <jpawlowski@google.com>
Mon, 2 Nov 2020 17:03:17 +0000 (17:03 +0000)
Bug: 142341141
Test: atest bluetooth_test_gd
Tag: #gd-refactor
Change-Id: I55e4c4f9b2e778d2960b98783715d1bc278bfa9a

gd/security/initial_informations.h
gd/security/internal/security_manager_impl.cc
gd/security/internal/security_manager_impl.h
gd/security/pairing_handler_le.cc
gd/security/pairing_handler_le_unittest.cc
gd/security/security_module.cc
gd/security/test/pairing_handler_le_pair_test.cc

index 2e28303..c5982bd 100644 (file)
@@ -79,6 +79,9 @@ struct InitialInformations {
   hci::Role my_role;
   hci::AddressWithType my_connection_address;
 
+  hci::AddressWithType my_identity_address;
+  crypto_toolbox::Octet16 my_identity_resolving_key;
+
   /* My capabilities, as in pairing request/response */
   struct {
     IoCapability io_capability;
index d5a5782..117e18d 100644 (file)
@@ -23,6 +23,7 @@
 #include "crypto_toolbox/crypto_toolbox.h"
 #include "hci/address_with_type.h"
 #include "os/log.h"
+#include "os/rand.h"
 #include "security/initial_informations.h"
 #include "security/internal/security_manager_impl.h"
 #include "security/pairing_handler_le.h"
@@ -77,17 +78,33 @@ void SecurityManagerImpl::Init() {
   ASSERT_LOG(storage_module_ != nullptr, "Storage module must not be null!");
   security_database_.LoadRecordsFromStorage();
 
-  // TODO(b/161543441): read the privacy policy from device-specific configuration, and IRK from config file.
+  storage::AdapterConfig adapter_config = storage_module_->GetAdapterConfig();
+  if (!adapter_config.GetLeIdentityResolvingKey()) {
+    auto mutation = storage_module_->Modify();
+    mutation.Add(adapter_config.SetLeIdentityResolvingKey(bluetooth::os::GenerateRandom<16>()));
+    mutation.Commit();
+  }
+
+  Address controllerAddress = controller_->GetMacAddress();
+  if (!adapter_config.GetAddress() || adapter_config.GetAddress().value() != controllerAddress) {
+    auto mutation = storage_module_->Modify();
+    mutation.Add(adapter_config.SetAddress(controllerAddress));
+    mutation.Commit();
+  }
+
+  local_identity_address_ =
+      hci::AddressWithType(adapter_config.GetAddress().value(), hci::AddressType::PUBLIC_DEVICE_ADDRESS);
+  local_identity_resolving_key_ = adapter_config.GetLeIdentityResolvingKey().value().bytes;
+
   hci::LeAddressManager::AddressPolicy address_policy = hci::LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS;
   hci::AddressWithType address_with_type(hci::Address{}, hci::AddressType::RANDOM_DEVICE_ADDRESS);
-  crypto_toolbox::Octet16 irk = {
-      0x44, 0xfb, 0x4b, 0x8d, 0x6c, 0x58, 0x21, 0x0c, 0xf9, 0x3d, 0xda, 0xf1, 0x64, 0xa3, 0xbb, 0x7f};
+
   /* 7 minutes minimum, 15 minutes maximum for random address refreshing */
   auto minimum_rotation_time = std::chrono::minutes(7);
   auto maximum_rotation_time = std::chrono::minutes(15);
 
   acl_manager_->SetPrivacyPolicyForInitiatorAddress(
-      address_policy, address_with_type, irk, minimum_rotation_time, maximum_rotation_time);
+      address_policy, address_with_type, local_identity_resolving_key_, minimum_rotation_time, maximum_rotation_time);
 }
 
 void SecurityManagerImpl::CreateBond(hci::AddressWithType device) {
@@ -492,6 +509,8 @@ void SecurityManagerImpl::OnSmpCommandLe(hci::AddressWithType device) {
     InitialInformations initial_informations{
         .my_role = my_role,
         .my_connection_address = channel->GetLinkOptions()->GetLocalAddress(),
+        .my_identity_address = local_identity_address_,
+        .my_identity_resolving_key = local_identity_resolving_key_,
         /*TODO: properly obtain capabilities from device-specific storage*/
         .myPairingCapabilities = {.io_capability = local_le_io_capability_,
                                   .oob_data_flag = local_le_oob_data_present_,
@@ -562,6 +581,8 @@ void SecurityManagerImpl::ConnectionIsReadyStartPairing(LeFixedChannelEntry* sto
   InitialInformations initial_informations{
       .my_role = channel->GetLinkOptions()->GetRole(),
       .my_connection_address = channel->GetLinkOptions()->GetLocalAddress(),
+      .my_identity_address = local_identity_address_,
+      .my_identity_resolving_key = local_identity_resolving_key_,
       /*TODO: properly obtain capabilities from device-specific storage*/
       .myPairingCapabilities = {.io_capability = local_le_io_capability_,
                                 .oob_data_flag = local_le_oob_data_present_,
@@ -624,6 +645,7 @@ SecurityManagerImpl::SecurityManagerImpl(
     channel::SecurityManagerChannel* security_manager_channel,
     hci::HciLayer* hci_layer,
     hci::AclManager* acl_manager,
+    hci::Controller* controller,
     storage::StorageModule* storage_module,
     neighbor::NameDbModule* name_db_module)
     : security_handler_(security_handler),
@@ -633,6 +655,7 @@ SecurityManagerImpl::SecurityManagerImpl(
           hci_layer->GetLeSecurityInterface(security_handler_->BindOn(this, &SecurityManagerImpl::OnHciLeEvent))),
       security_manager_channel_(security_manager_channel),
       acl_manager_(acl_manager),
+      controller_(controller),
       storage_module_(storage_module),
       security_record_storage_(storage_module, security_handler),
       security_database_(security_record_storage_),
index cb3ecb3..aecf0cd 100644 (file)
@@ -21,6 +21,7 @@
 #include <utility>
 
 #include "hci/acl_manager.h"
+#include "hci/controller.h"
 #include "l2cap/classic/security_enforcement_interface.h"
 #include "l2cap/le/l2cap_le_module.h"
 #include "l2cap/le/security_enforcement_interface.h"
@@ -58,6 +59,7 @@ class SecurityManagerImpl : public channel::ISecurityManagerChannelListener, pub
       channel::SecurityManagerChannel* security_manager_channel,
       hci::HciLayer* hci_layer,
       hci::AclManager* acl_manager,
+      hci::Controller* controller,
       storage::StorageModule* storage_module,
       neighbor::NameDbModule* name_db_module);
 
@@ -217,6 +219,7 @@ class SecurityManagerImpl : public channel::ISecurityManagerChannelListener, pub
   void OnPairingFinished(bluetooth::security::PairingResultOrFailure pairing_result);
   void OnHciLeEvent(hci::LeMetaEventView event);
   LeFixedChannelEntry* FindStoredLeChannel(const hci::AddressWithType& device);
+  LeFixedChannelEntry* FindStoredLeChannel(uint8_t connection_handle);
   bool EraseStoredLeChannel(const hci::AddressWithType& device);
   void InternalEnforceSecurityPolicy(
       hci::AddressWithType remote,
@@ -233,6 +236,7 @@ class SecurityManagerImpl : public channel::ISecurityManagerChannelListener, pub
   hci::LeSecurityInterface* hci_security_interface_le_ __attribute__((unused));
   channel::SecurityManagerChannel* security_manager_channel_;
   hci::AclManager* acl_manager_;
+  hci::Controller* controller_;
   storage::StorageModule* storage_module_ __attribute__((unused));
   record::SecurityRecordStorage security_record_storage_;
   record::SecurityRecordDatabase security_database_;
@@ -250,6 +254,8 @@ class SecurityManagerImpl : public channel::ISecurityManagerChannelListener, pub
   std::optional<crypto_toolbox::Octet16> remote_oob_data_le_sc_c_;
   std::optional<crypto_toolbox::Octet16> remote_oob_data_le_sc_r_;
   std::optional<FacadeDisconnectCallback> facade_disconnect_callback_;
+  hci::AddressWithType local_identity_address_;
+  crypto_toolbox::Octet16 local_identity_resolving_key_;
 
   struct PendingSecurityEnforcementEntry {
     l2cap::classic::SecurityPolicy policy_;
index c2673c7..556de53 100644 (file)
@@ -208,7 +208,8 @@ void PairingHandlerLe::PairingMain(InitialInformations i) {
 
   i.OnPairingFinished(PairingResult{
       .connection_address = i.remote_connection_address,
-      .distributed_keys = std::get<DistributedKeys>(keyExchangeStatus),
+      .distributed_keys = distributed_keys,
+      .key_size = key_size,
   });
 
   LOG_INFO("Pairing finished successfully.");
@@ -340,9 +341,10 @@ DistributedKeysOrFailure PairingHandlerLe::DistributeKeys(const InitialInformati
   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;
-  AddrType my_identity_address_type = AddrType::PUBLIC;
+  Octet16 my_irk = i.my_identity_resolving_key;
+  Address my_identity_address = i.my_identity_address.GetAddress();
+  AddrType my_identity_address_type =
+      static_cast<bluetooth::security::AddrType>(i.my_identity_address.GetAddressType());
   Octet16 my_signature_key{0};
 
   if (IAmCentral(i)) {
index 8cc3193..690c080 100644 (file)
@@ -134,6 +134,9 @@ class PairingHandlerUnitTest : public testing::Test {
 InitialInformations initial_informations{
     .my_role = hci::Role::CENTRAL,
     .my_connection_address = {{}, hci::AddressType::PUBLIC_DEVICE_ADDRESS},
+    .my_identity_address = {{}, hci::AddressType::PUBLIC_DEVICE_ADDRESS},
+    .my_identity_resolving_key =
+        {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
 
     .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
                               .oob_data_flag = OobDataFlag::NOT_PRESENT,
@@ -271,6 +274,9 @@ TEST_F(PairingHandlerUnitTest, test_secure_connections_just_works) {
 InitialInformations initial_informations_trsi{
     .my_role = hci::Role::CENTRAL,
     .my_connection_address = hci::AddressWithType(),
+    .my_identity_address = {{}, hci::AddressType::PUBLIC_DEVICE_ADDRESS},
+    .my_identity_resolving_key =
+        {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
 
     .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
                               .oob_data_flag = OobDataFlag::NOT_PRESENT,
@@ -310,6 +316,9 @@ TEST_F(PairingHandlerUnitTest, test_remote_peripheral_initiating) {
 InitialInformations initial_informations_trmi{
     .my_role = hci::Role::PERIPHERAL,
     .my_connection_address = hci::AddressWithType(),
+    .my_identity_address = {{}, hci::AddressType::PUBLIC_DEVICE_ADDRESS},
+    .my_identity_resolving_key =
+        {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
 
     .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
                               .oob_data_flag = OobDataFlag::NOT_PRESENT,
index 8d1839b..d753780 100644 (file)
@@ -44,6 +44,7 @@ struct SecurityModule::impl {
       l2cap::classic::L2capClassicModule* l2cap_classic_module,
       hci::HciLayer* hci_layer,
       hci::AclManager* acl_manager,
+      hci::Controller* controller,
       storage::StorageModule* storage_module,
       neighbor::NameDbModule* name_db_module)
       : security_handler_(security_handler),
@@ -52,6 +53,7 @@ struct SecurityModule::impl {
         security_manager_channel_(new channel::SecurityManagerChannel(security_handler_, hci_layer)),
         hci_layer_(hci_layer),
         acl_manager_(acl_manager),
+        controller_(controller),
         storage_module_(storage_module),
         l2cap_security_interface_(&security_manager_impl, security_handler),
         name_db_module_(name_db_module) {
@@ -67,6 +69,7 @@ struct SecurityModule::impl {
   channel::SecurityManagerChannel* security_manager_channel_;
   hci::HciLayer* hci_layer_;
   hci::AclManager* acl_manager_;
+  hci::Controller* controller_;
   storage::StorageModule* storage_module_;
   L2capSecurityModuleInterface l2cap_security_interface_;
   neighbor::NameDbModule* name_db_module_;
@@ -76,6 +79,7 @@ struct SecurityModule::impl {
                                                       security_manager_channel_,
                                                       hci_layer_,
                                                       acl_manager_,
+                                                      controller_,
                                                       storage_module_,
                                                       name_db_module_};
 
@@ -91,6 +95,7 @@ void SecurityModule::ListDependencies(ModuleList* list) {
   list->add<l2cap::classic::L2capClassicModule>();
   list->add<hci::HciLayer>();
   list->add<hci::AclManager>();
+  list->add<hci::Controller>();
   list->add<storage::StorageModule>();
   list->add<neighbor::NameDbModule>();
 }
@@ -102,6 +107,7 @@ void SecurityModule::Start() {
       GetDependency<l2cap::classic::L2capClassicModule>(),
       GetDependency<hci::HciLayer>(),
       GetDependency<hci::AclManager>(),
+      GetDependency<hci::Controller>(),
       GetDependency<storage::StorageModule>(),
       GetDependency<neighbor::NameDbModule>());
 
index f6386da..397ad4f 100644 (file)
@@ -85,9 +85,17 @@ namespace security {
 namespace {
 Address ADDRESS_CENTRAL{{0x26, 0x64, 0x76, 0x86, 0xab, 0xba}};
 AddressType ADDRESS_TYPE_CENTRAL = AddressType::RANDOM_DEVICE_ADDRESS;
+Address IDENTITY_ADDRESS_CENTRAL{{0x12, 0x34, 0x56, 0x78, 0x90, 0xaa}};
+AddressType IDENTITY_ADDRESS_TYPE_CENTRAL = AddressType::PUBLIC_DEVICE_ADDRESS;
+crypto_toolbox::Octet16 IRK_CENTRAL = {
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
 
 Address ADDRESS_PERIPHERAL{{0x33, 0x58, 0x24, 0x76, 0x11, 0x89}};
 AddressType ADDRESS_TYPE_PERIPHERAL = AddressType::RANDOM_DEVICE_ADDRESS;
+Address IDENTITY_ADDRESS_PERIPHERAL{{0x21, 0x43, 0x65, 0x87, 0x09, 0x44}};
+AddressType IDENTITY_ADDRESS_TYPE_PERIPHERAL = AddressType::PUBLIC_DEVICE_ADDRESS;
+crypto_toolbox::Octet16 IRK_PERIPHERAL = {
+    0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
 
 std::optional<PairingResultOrFailure> pairing_result_central;
 std::optional<PairingResultOrFailure> pairing_result_peripheral;
@@ -167,6 +175,8 @@ class PairingHandlerPairTest : public testing::Test {
     central_setup = {
         .my_role = hci::Role::CENTRAL,
         .my_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
+        .my_identity_address = {IDENTITY_ADDRESS_CENTRAL, IDENTITY_ADDRESS_TYPE_CENTRAL},
+        .my_identity_resolving_key = IRK_CENTRAL,
 
         .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
                                   .oob_data_flag = OobDataFlag::NOT_PRESENT,
@@ -190,6 +200,9 @@ class PairingHandlerPairTest : public testing::Test {
         .my_role = hci::Role::PERIPHERAL,
 
         .my_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
+        .my_identity_address = {IDENTITY_ADDRESS_PERIPHERAL, IDENTITY_ADDRESS_TYPE_PERIPHERAL},
+        .my_identity_resolving_key = IRK_PERIPHERAL,
+
         .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
                                   .oob_data_flag = OobDataFlag::NOT_PRESENT,
                                   .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
@@ -336,12 +349,26 @@ TEST_F(PairingHandlerPairTest, test_secure_connections_just_works) {
 
   EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_central.value()));
   EXPECT_TRUE(std::holds_alternative<PairingResult>(pairing_result_peripheral.value()));
+
+  auto central_result = std::get<PairingResult>(pairing_result_central.value());
+  ASSERT_EQ(central_result.distributed_keys.remote_identity_address->GetAddress(), IDENTITY_ADDRESS_PERIPHERAL);
+  ASSERT_EQ(
+      central_result.distributed_keys.remote_identity_address->GetAddressType(), IDENTITY_ADDRESS_TYPE_PERIPHERAL);
+  ASSERT_EQ(*central_result.distributed_keys.remote_irk, IRK_PERIPHERAL);
+
+  auto peripheral_result = std::get<PairingResult>(pairing_result_peripheral.value());
+  ASSERT_EQ(peripheral_result.distributed_keys.remote_identity_address->GetAddress(), IDENTITY_ADDRESS_CENTRAL);
+  ASSERT_EQ(
+      peripheral_result.distributed_keys.remote_identity_address->GetAddressType(), IDENTITY_ADDRESS_TYPE_CENTRAL);
+  ASSERT_EQ(*peripheral_result.distributed_keys.remote_irk, IRK_CENTRAL);
 }
 
 TEST_F(PairingHandlerPairTest, test_secure_connections_just_works_peripheral_initiated) {
   central_setup = {
       .my_role = hci::Role::CENTRAL,
       .my_connection_address = {ADDRESS_CENTRAL, ADDRESS_TYPE_CENTRAL},
+      .my_identity_address = {IDENTITY_ADDRESS_CENTRAL, IDENTITY_ADDRESS_TYPE_CENTRAL},
+      .my_identity_resolving_key = IRK_CENTRAL,
       .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
                                 .oob_data_flag = OobDataFlag::NOT_PRESENT,
                                 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,
@@ -362,6 +389,8 @@ TEST_F(PairingHandlerPairTest, test_secure_connections_just_works_peripheral_ini
   peripheral_setup = {
       .my_role = hci::Role::PERIPHERAL,
       .my_connection_address = {ADDRESS_PERIPHERAL, ADDRESS_TYPE_PERIPHERAL},
+      .my_identity_address = {IDENTITY_ADDRESS_PERIPHERAL, IDENTITY_ADDRESS_TYPE_PERIPHERAL},
+      .my_identity_resolving_key = IRK_PERIPHERAL,
       .myPairingCapabilities = {.io_capability = IoCapability::NO_INPUT_NO_OUTPUT,
                                 .oob_data_flag = OobDataFlag::NOT_PRESENT,
                                 .auth_req = AuthReqMaskBondingFlag | AuthReqMaskMitm | AuthReqMaskSc,