1 #include "hci/le_address_manager.h"
2 #include "os/log.h"
3 #include "os/rand.h"
4 
5 namespace bluetooth {
6 namespace hci {
7 
8 static constexpr uint8_t BLE_ADDR_MASK = 0xc0u;
9 
LeAddressManager(common::Callback<void (std::unique_ptr<CommandPacketBuilder>)> enqueue_command,os::Handler * handler,Address public_address,uint8_t connect_list_size,uint8_t resolving_list_size)10 LeAddressManager::LeAddressManager(
11     common::Callback<void(std::unique_ptr<CommandPacketBuilder>)> enqueue_command,
12     os::Handler* handler,
13     Address public_address,
14     uint8_t connect_list_size,
15     uint8_t resolving_list_size)
16     : enqueue_command_(enqueue_command),
17       handler_(handler),
18       public_address_(public_address),
19       connect_list_size_(connect_list_size),
20       resolving_list_size_(resolving_list_size){};
21 
~LeAddressManager()22 LeAddressManager::~LeAddressManager() {
23   if (address_rotation_alarm_ != nullptr) {
24     address_rotation_alarm_->Cancel();
25     address_rotation_alarm_.reset();
26   }
27 }
28 
29 // Aborts if called more than once
SetPrivacyPolicyForInitiatorAddress(AddressPolicy address_policy,AddressWithType fixed_address,crypto_toolbox::Octet16 rotation_irk,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)30 void LeAddressManager::SetPrivacyPolicyForInitiatorAddress(
31     AddressPolicy address_policy,
32     AddressWithType fixed_address,
33     crypto_toolbox::Octet16 rotation_irk,
34     std::chrono::milliseconds minimum_rotation_time,
35     std::chrono::milliseconds maximum_rotation_time) {
36   ASSERT(address_policy_ == AddressPolicy::POLICY_NOT_SET);
37   ASSERT(address_policy != AddressPolicy::POLICY_NOT_SET);
38   ASSERT_LOG(registered_clients_.empty(), "Policy must be set before clients are registered.");
39   address_policy_ = address_policy;
40 
41   switch (address_policy_) {
42     case AddressPolicy::USE_PUBLIC_ADDRESS:
43       le_address_ = fixed_address;
44       break;
45     case AddressPolicy::USE_STATIC_ADDRESS: {
46       auto addr = fixed_address.GetAddress();
47       auto address = addr.address;
48       // The two most significant bits of the static address shall be equal to 1
49       ASSERT_LOG((address[5] & BLE_ADDR_MASK) == BLE_ADDR_MASK, "The two most significant bits shall be equal to 1");
50       // Bits of the random part of the address shall not be all 1 or all 0
51       if ((address[0] == 0x00 && address[1] == 0x00 && address[2] == 0x00 && address[3] == 0x00 && address[4] == 0x00 &&
52            address[5] == BLE_ADDR_MASK) ||
53           (address[0] == 0xFF && address[1] == 0xFF && address[2] == 0xFF && address[3] == 0xFF && address[4] == 0xFF &&
54            address[5] == 0xFF)) {
55         LOG_ALWAYS_FATAL("Bits of the random part of the address shall not be all 1 or all 0");
56       }
57       le_address_ = fixed_address;
58       auto packet = hci::LeSetRandomAddressBuilder::Create(le_address_.GetAddress());
59       handler_->Post(common::BindOnce(enqueue_command_, std::move(packet)));
60     } break;
61     case AddressPolicy::USE_NON_RESOLVABLE_ADDRESS:
62     case AddressPolicy::USE_RESOLVABLE_ADDRESS:
63       rotation_irk_ = rotation_irk;
64       minimum_rotation_time_ = minimum_rotation_time;
65       maximum_rotation_time_ = maximum_rotation_time;
66       address_rotation_alarm_ = std::make_unique<os::Alarm>(handler_);
67       break;
68     case AddressPolicy::POLICY_NOT_SET:
69       LOG_ALWAYS_FATAL("invalid parameters");
70   }
71 }
72 
73 // TODO(jpawlowski): remove once we have config file abstraction in cert tests
SetPrivacyPolicyForInitiatorAddressForTest(AddressPolicy address_policy,AddressWithType fixed_address,crypto_toolbox::Octet16 rotation_irk,std::chrono::milliseconds minimum_rotation_time,std::chrono::milliseconds maximum_rotation_time)74 void LeAddressManager::SetPrivacyPolicyForInitiatorAddressForTest(
75     AddressPolicy address_policy,
76     AddressWithType fixed_address,
77     crypto_toolbox::Octet16 rotation_irk,
78     std::chrono::milliseconds minimum_rotation_time,
79     std::chrono::milliseconds maximum_rotation_time) {
80   ASSERT(address_policy != AddressPolicy::POLICY_NOT_SET);
81   ASSERT_LOG(registered_clients_.empty(), "Policy must be set before clients are registered.");
82   address_policy_ = address_policy;
83 
84   switch (address_policy_) {
85     case AddressPolicy::USE_PUBLIC_ADDRESS:
86       le_address_ = fixed_address;
87       break;
88     case AddressPolicy::USE_STATIC_ADDRESS: {
89       auto addr = fixed_address.GetAddress();
90       auto address = addr.address;
91       // The two most significant bits of the static address shall be equal to 1
92       ASSERT_LOG((address[5] & BLE_ADDR_MASK) == BLE_ADDR_MASK, "The two most significant bits shall be equal to 1");
93       // Bits of the random part of the address shall not be all 1 or all 0
94       if ((address[0] == 0x00 && address[1] == 0x00 && address[2] == 0x00 && address[3] == 0x00 && address[4] == 0x00 &&
95            address[5] == BLE_ADDR_MASK) ||
96           (address[0] == 0xFF && address[1] == 0xFF && address[2] == 0xFF && address[3] == 0xFF && address[4] == 0xFF &&
97            address[5] == 0xFF)) {
98         LOG_ALWAYS_FATAL("Bits of the random part of the address shall not be all 1 or all 0");
99       }
100       le_address_ = fixed_address;
101       auto packet = hci::LeSetRandomAddressBuilder::Create(le_address_.GetAddress());
102       handler_->Call(enqueue_command_, std::move(packet));
103     } break;
104     case AddressPolicy::USE_NON_RESOLVABLE_ADDRESS:
105     case AddressPolicy::USE_RESOLVABLE_ADDRESS:
106       rotation_irk_ = rotation_irk;
107       minimum_rotation_time_ = minimum_rotation_time;
108       maximum_rotation_time_ = maximum_rotation_time;
109       address_rotation_alarm_ = std::make_unique<os::Alarm>(handler_);
110       break;
111     case AddressPolicy::POLICY_NOT_SET:
112       LOG_ALWAYS_FATAL("invalid parameters");
113   }
114 }
115 
Register(LeAddressManagerCallback * callback)116 LeAddressManager::AddressPolicy LeAddressManager::Register(LeAddressManagerCallback* callback) {
117   handler_->BindOnceOn(this, &LeAddressManager::register_client, callback).Invoke();
118   return address_policy_;
119 }
120 
register_client(LeAddressManagerCallback * callback)121 void LeAddressManager::register_client(LeAddressManagerCallback* callback) {
122   registered_clients_.insert(std::pair<LeAddressManagerCallback*, ClientState>(callback, ClientState::RESUMED));
123   if (address_policy_ == AddressPolicy::POLICY_NOT_SET || address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS ||
124       address_policy_ == AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
125     prepare_to_rotate();
126   }
127 }
128 
Unregister(LeAddressManagerCallback * callback)129 void LeAddressManager::Unregister(LeAddressManagerCallback* callback) {
130   handler_->BindOnceOn(this, &LeAddressManager::unregister_client, callback).Invoke();
131 }
132 
unregister_client(LeAddressManagerCallback * callback)133 void LeAddressManager::unregister_client(LeAddressManagerCallback* callback) {
134   registered_clients_.erase(callback);
135   if (registered_clients_.empty() && address_rotation_alarm_ != nullptr) {
136     address_rotation_alarm_->Cancel();
137   }
138 }
139 
AckPause(LeAddressManagerCallback * callback)140 void LeAddressManager::AckPause(LeAddressManagerCallback* callback) {
141   handler_->BindOnceOn(this, &LeAddressManager::ack_pause, callback).Invoke();
142 }
143 
AckResume(LeAddressManagerCallback * callback)144 void LeAddressManager::AckResume(LeAddressManagerCallback* callback) {
145   handler_->BindOnceOn(this, &LeAddressManager::ack_resume, callback).Invoke();
146 }
147 
GetCurrentAddress()148 AddressWithType LeAddressManager::GetCurrentAddress() {
149   ASSERT(address_policy_ != AddressPolicy::POLICY_NOT_SET);
150   return le_address_;
151 }
152 
GetAnotherAddress()153 AddressWithType LeAddressManager::GetAnotherAddress() {
154   ASSERT(
155       address_policy_ == AddressPolicy::USE_NON_RESOLVABLE_ADDRESS ||
156       address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS);
157   hci::Address address = generate_rpa();
158   auto random_address = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
159   return random_address;
160 }
161 
pause_registered_clients()162 void LeAddressManager::pause_registered_clients() {
163   for (auto client : registered_clients_) {
164     if (client.second != ClientState::PAUSED && client.second != ClientState::WAITING_FOR_PAUSE) {
165       client.second = ClientState::WAITING_FOR_PAUSE;
166       client.first->OnPause();
167     }
168   }
169 }
170 
ack_pause(LeAddressManagerCallback * callback)171 void LeAddressManager::ack_pause(LeAddressManagerCallback* callback) {
172   ASSERT(registered_clients_.find(callback) != registered_clients_.end());
173   registered_clients_.find(callback)->second = ClientState::PAUSED;
174   for (auto client : registered_clients_) {
175     if (client.second != ClientState::PAUSED) {
176       // make sure all client paused
177       return;
178     }
179   }
180   handle_next_command();
181 }
182 
resume_registered_clients()183 void LeAddressManager::resume_registered_clients() {
184   // Do not resume clients if cached command is not empty
185   if (!cached_commands_.empty()) {
186     handle_next_command();
187     return;
188   }
189 
190   for (auto client : registered_clients_) {
191     client.second = ClientState::WAITING_FOR_RESUME;
192     client.first->OnResume();
193   }
194 }
195 
ack_resume(LeAddressManagerCallback * callback)196 void LeAddressManager::ack_resume(LeAddressManagerCallback* callback) {
197   ASSERT(registered_clients_.find(callback) != registered_clients_.end());
198   registered_clients_.find(callback)->second = ClientState::RESUMED;
199 }
200 
prepare_to_rotate()201 void LeAddressManager::prepare_to_rotate() {
202   Command command = {CommandType::ROTATE_RANDOM_ADDRESS, nullptr};
203   cached_commands_.push(std::move(command));
204   pause_registered_clients();
205 }
206 
rotate_random_address()207 void LeAddressManager::rotate_random_address() {
208   if (address_policy_ != AddressPolicy::USE_RESOLVABLE_ADDRESS &&
209       address_policy_ != AddressPolicy::USE_NON_RESOLVABLE_ADDRESS) {
210     return;
211   }
212 
213   address_rotation_alarm_->Schedule(
214       common::BindOnce(&LeAddressManager::prepare_to_rotate, common::Unretained(this)),
215       get_next_private_address_interval_ms());
216 
217   hci::Address address;
218   if (address_policy_ == AddressPolicy::USE_RESOLVABLE_ADDRESS) {
219     address = generate_rpa();
220   } else {
221     address = generate_nrpa();
222   }
223   auto packet = hci::LeSetRandomAddressBuilder::Create(address);
224   enqueue_command_.Run(std::move(packet));
225   le_address_ = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS);
226 }
227 
on_le_set_random_address_complete(CommandCompleteView view)228 void LeAddressManager::on_le_set_random_address_complete(CommandCompleteView view) {
229   auto complete_view = LeSetRandomAddressCompleteView::Create(view);
230   if (!complete_view.IsValid()) {
231     LOG_ALWAYS_FATAL("Received on_le_set_random_address_complete with invalid packet");
232   } else if (complete_view.GetStatus() != ErrorCode::SUCCESS) {
233     auto status = complete_view.GetStatus();
234     std::string error_code = ErrorCodeText(status);
235     LOG_ALWAYS_FATAL("Received on_le_set_random_address_complete with error code %s", error_code.c_str());
236   }
237   if (cached_commands_.empty()) {
238     handler_->BindOnceOn(this, &LeAddressManager::resume_registered_clients).Invoke();
239   } else {
240     handler_->BindOnceOn(this, &LeAddressManager::handle_next_command).Invoke();
241   }
242 }
243 
244 /* This function generates Resolvable Private Address (RPA) from Identity
245  * Resolving Key |irk| and |prand|*/
generate_rpa()246 hci::Address LeAddressManager::generate_rpa() {
247   // most significant bit, bit7, bit6 is 01 to be resolvable random
248   // Bits of the random part of prand shall not be all 1 or all 0
249   std::array<uint8_t, 3> prand = os::GenerateRandom<3>();
250   constexpr uint8_t BLE_RESOLVE_ADDR_MSB = 0x40;
251   prand[2] &= ~BLE_ADDR_MASK;
252   if ((prand[0] == 0x00 && prand[1] == 0x00 && prand[2] == 0x00) ||
253       (prand[0] == 0xFF && prand[1] == 0xFF && prand[2] == 0x3F)) {
254     prand[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
255   }
256   prand[2] |= BLE_RESOLVE_ADDR_MSB;
257 
258   hci::Address address;
259   address.address[3] = prand[0];
260   address.address[4] = prand[1];
261   address.address[5] = prand[2];
262 
263   /* encrypt with IRK */
264   crypto_toolbox::Octet16 p = crypto_toolbox::aes_128(rotation_irk_, prand.data(), 3);
265 
266   /* set hash to be LSB of rpAddress */
267   address.address[0] = p[0];
268   address.address[1] = p[1];
269   address.address[2] = p[2];
270   return address;
271 }
272 
273 // This function generates NON-Resolvable Private Address (NRPA)
generate_nrpa()274 hci::Address LeAddressManager::generate_nrpa() {
275   // The two most significant bits of the address shall be equal to 0
276   // Bits of the random part of the address shall not be all 1 or all 0
277   std::array<uint8_t, 6> random = os::GenerateRandom<6>();
278   random[5] &= ~BLE_ADDR_MASK;
279   if ((random[0] == 0x00 && random[1] == 0x00 && random[2] == 0x00 && random[3] == 0x00 && random[4] == 0x00 &&
280        random[5] == 0x00) ||
281       (random[0] == 0xFF && random[1] == 0xFF && random[2] == 0xFF && random[3] == 0xFF && random[4] == 0xFF &&
282        random[5] == 0x3F)) {
283     random[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
284   }
285 
286   hci::Address address;
287   address.FromOctets(random.data());
288 
289   // the address shall not be equal to the public address
290   while (address == public_address_) {
291     address.address[0] = (uint8_t)(os::GenerateRandom() % 0xFE + 1);
292   }
293 
294   return address;
295 }
296 
get_next_private_address_interval_ms()297 std::chrono::milliseconds LeAddressManager::get_next_private_address_interval_ms() {
298   auto interval_random_part_max_ms = maximum_rotation_time_ - minimum_rotation_time_;
299   auto random_ms = std::chrono::milliseconds(os::GenerateRandom()) % (interval_random_part_max_ms);
300   return minimum_rotation_time_ + random_ms;
301 }
302 
GetConnectListSize()303 uint8_t LeAddressManager::GetConnectListSize() {
304   return connect_list_size_;
305 }
306 
GetResolvingListSize()307 uint8_t LeAddressManager::GetResolvingListSize() {
308   return resolving_list_size_;
309 }
310 
handle_next_command()311 void LeAddressManager::handle_next_command() {
312   ASSERT(!cached_commands_.empty());
313   auto command = std::move(cached_commands_.front());
314   cached_commands_.pop();
315 
316   if (command.command_type == CommandType::ROTATE_RANDOM_ADDRESS) {
317     rotate_random_address();
318   } else {
319     enqueue_command_.Run(std::move(command.command_packet));
320   }
321 }
322 
AddDeviceToConnectList(ConnectListAddressType connect_list_address_type,bluetooth::hci::Address address)323 void LeAddressManager::AddDeviceToConnectList(
324     ConnectListAddressType connect_list_address_type, bluetooth::hci::Address address) {
325   auto packet_builder = hci::LeAddDeviceToConnectListBuilder::Create(connect_list_address_type, address);
326   Command command = {CommandType::ADD_DEVICE_TO_CONNECT_LIST, std::move(packet_builder)};
327   handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
328   cached_commands_.push(std::move(command));
329 }
330 
AddDeviceToResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address,const std::array<uint8_t,16> & peer_irk,const std::array<uint8_t,16> & local_irk)331 void LeAddressManager::AddDeviceToResolvingList(
332     PeerAddressType peer_identity_address_type,
333     Address peer_identity_address,
334     const std::array<uint8_t, 16>& peer_irk,
335     const std::array<uint8_t, 16>& local_irk) {
336   auto packet_builder = hci::LeAddDeviceToResolvingListBuilder::Create(
337       peer_identity_address_type, peer_identity_address, peer_irk, local_irk);
338   Command command = {CommandType::ADD_DEVICE_TO_RESOLVING_LIST, std::move(packet_builder)};
339   handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
340   cached_commands_.push(std::move(command));
341 }
342 
RemoveDeviceFromConnectList(ConnectListAddressType connect_list_address_type,bluetooth::hci::Address address)343 void LeAddressManager::RemoveDeviceFromConnectList(
344     ConnectListAddressType connect_list_address_type, bluetooth::hci::Address address) {
345   auto packet_builder = hci::LeRemoveDeviceFromConnectListBuilder::Create(connect_list_address_type, address);
346   Command command = {CommandType::REMOVE_DEVICE_FROM_CONNECT_LIST, std::move(packet_builder)};
347   handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
348   cached_commands_.push(std::move(command));
349 }
350 
RemoveDeviceFromResolvingList(PeerAddressType peer_identity_address_type,Address peer_identity_address)351 void LeAddressManager::RemoveDeviceFromResolvingList(
352     PeerAddressType peer_identity_address_type, Address peer_identity_address) {
353   auto packet_builder =
354       hci::LeRemoveDeviceFromResolvingListBuilder::Create(peer_identity_address_type, peer_identity_address);
355   Command command = {CommandType::REMOVE_DEVICE_FROM_RESOLVING_LIST, std::move(packet_builder)};
356   handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
357   cached_commands_.push(std::move(command));
358 }
359 
ClearConnectList()360 void LeAddressManager::ClearConnectList() {
361   auto packet_builder = hci::LeClearConnectListBuilder::Create();
362   Command command = {CommandType::CLEAR_CONNECT_LIST, std::move(packet_builder)};
363   handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
364   cached_commands_.push(std::move(command));
365 }
366 
ClearResolvingList()367 void LeAddressManager::ClearResolvingList() {
368   auto packet_builder = hci::LeClearResolvingListBuilder::Create();
369   Command command = {CommandType::CLEAR_RESOLVING_LIST, std::move(packet_builder)};
370   handler_->BindOnceOn(this, &LeAddressManager::pause_registered_clients).Invoke();
371   cached_commands_.push(std::move(command));
372 }
373 
OnCommandComplete(bluetooth::hci::CommandCompleteView view)374 void LeAddressManager::OnCommandComplete(bluetooth::hci::CommandCompleteView view) {
375   if (!view.IsValid()) {
376     LOG_ERROR("Received command complete with invalid packet");
377     return;
378   }
379   std::string op_code = OpCodeText(view.GetCommandOpCode());
380   LOG_DEBUG("Received command complete with op_code %s", op_code.c_str());
381 
382   // The command was sent before any client registered, we can make sure all the clients paused when command complete.
383   if (view.GetCommandOpCode() == OpCode::LE_SET_RANDOM_ADDRESS &&
384       address_policy_ == AddressPolicy::USE_STATIC_ADDRESS) {
385     LOG_DEBUG("Received LE_SET_RANDOM_ADDRESS complete and Address policy is USE_STATIC_ADDRESS, return");
386     return;
387   }
388 
389   if (cached_commands_.empty()) {
390     handler_->BindOnceOn(this, &LeAddressManager::resume_registered_clients).Invoke();
391   } else {
392     handler_->BindOnceOn(this, &LeAddressManager::handle_next_command).Invoke();
393   }
394 }
395 
396 }  // namespace hci
397 }  // namespace bluetooth
398