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