From 16c16453467a03cd245cd5a07428a476ca618eb5 Mon Sep 17 00:00:00 2001 From: Myles Watson <mylesgw@google.com> Date: Wed, 3 Nov 2021 09:57:11 -0700 Subject: [PATCH] RootCanal: Generate RPA for connection Bug: 202018502 Test: cert/run Tag: #feature Change-Id: I9e9ca3c27f41921777d940946475dfc5f79ab4ac --- .../model/controller/link_layer_controller.cc | 78 ++++++++++++++++--- .../model/controller/link_layer_controller.h | 2 + 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc b/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc index 091b700edd8..e7d99c2fcc5 100644 --- a/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc +++ b/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc @@ -208,6 +208,11 @@ void LinkLayerController::IncomingPacket( address_matches = true; } + // Check current connection address + if (destination_address == le_connecting_rpa_) { + address_matches = true; + } + // Check advertising addresses for (const auto& advertiser : advertisers_) { if (advertiser.IsEnabled() && @@ -1163,6 +1168,40 @@ static bool rpa_matches_irk( return (memcmp(x.data(), &hash[0], 3) == 0); } +static Address generate_rpa( + std::array<uint8_t, LinkLayerController::kIrkSize> irk) { + // most significant bit, bit7, bit6 is 01 to be resolvable random + // Bits of the random part of prand shall not be all 1 or all 0 + std::array<uint8_t, 3> prand; + prand[0] = std::rand(); + prand[1] = std::rand(); + prand[2] = std::rand(); + + constexpr uint8_t BLE_RESOLVE_ADDR_MSB = 0x40; + prand[2] &= ~0xC0; // BLE Address mask + if ((prand[0] == 0x00 && prand[1] == 0x00 && prand[2] == 0x00) || + (prand[0] == 0xFF && prand[1] == 0xFF && prand[2] == 0x3F)) { + prand[0] = (uint8_t)(std::rand() % 0xFE + 1); + } + prand[2] |= BLE_RESOLVE_ADDR_MSB; + + Address rpa; + rpa.address[3] = prand[0]; + rpa.address[4] = prand[1]; + rpa.address[5] = prand[2]; + + /* encrypt with IRK */ + bluetooth::crypto_toolbox::Octet16 p = + bluetooth::crypto_toolbox::aes_128(irk, prand.data(), 3); + + /* set hash to be LSB of rpAddress */ + rpa.address[0] = p[0]; + rpa.address[1] = p[1]; + rpa.address[2] = p[2]; + LOG_INFO("RPA %s", rpa.ToString().c_str()); + return rpa; +} + void LinkLayerController::IncomingLeAdvertisementPacket( model::packets::LinkLayerPacketView incoming) { // TODO: Handle multiple advertisements per packet. @@ -1249,11 +1288,17 @@ void LinkLayerController::IncomingLeAdvertisementPacket( Address resolved_address = address; uint8_t resolved_address_type = static_cast<uint8_t>(address_type); bool resolved = false; - for (const auto& entry : le_resolving_list_) { - if (rpa_matches_irk(address, entry.peer_irk)) { - resolved = true; - resolved_address = entry.address; - resolved_address_type = entry.address_type; + Address rpa; + if (le_resolving_list_enabled_) { + for (const auto& entry : le_resolving_list_) { + if (rpa_matches_irk(address, entry.peer_irk)) { + LOG_INFO("Matched against IRK for %s", + entry.address.ToString().c_str()); + resolved = true; + resolved_address = entry.address; + resolved_address_type = entry.address_type; + rpa = generate_rpa(entry.local_irk); + } } } @@ -1283,10 +1328,22 @@ void LinkLayerController::IncomingLeAdvertisementPacket( case bluetooth::hci::OwnAddressType::RANDOM_DEVICE_ADDRESS: own_address = properties_.GetLeAddress(); break; - default: - LOG_ALWAYS_FATAL( - "Unhandled connection address type %s", - bluetooth::hci::OwnAddressTypeText(own_address_type).c_str()); + case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS: + if (resolved) { + own_address = rpa; + le_connecting_rpa_ = rpa; + } else { + own_address = properties_.GetAddress(); + } + break; + case bluetooth::hci::OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS: + if (resolved) { + own_address = rpa; + le_connecting_rpa_ = rpa; + } else { + own_address = properties_.GetLeAddress(); + } + break; } LOG_INFO("Connecting to %s (type %hhx) own_address %s (type %hhx)", incoming.GetSourceAddress().ToString().c_str(), address_type, @@ -1325,6 +1382,9 @@ uint16_t LinkLayerController::HandleLeConnection(AddressWithType address, static_cast<bluetooth::hci::ClockAccuracy>(0x00)); send_event_(std::move(packet)); } + if (own_address.GetAddress() == le_connecting_rpa_) { + le_connecting_rpa_ = Address::kEmpty; + } return handle; } diff --git a/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h b/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h index f3ab29892fe..37bdd170f1e 100644 --- a/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h +++ b/system/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h @@ -466,6 +466,8 @@ class LinkLayerController { std::vector<ResolvingListEntry> le_resolving_list_; bool le_resolving_list_enabled_{false}; + Address le_connecting_rpa_; + std::array<LeAdvertiser, 7> advertisers_; bluetooth::hci::OpCode le_scan_enable_{bluetooth::hci::OpCode::NONE}; -- GitLab