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