1 /******************************************************************************
2 *
3 * Copyright 2014 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_btif_config"
20
21 #include "btif_config.h"
22
23 #include <base/logging.h>
24 #include <openssl/rand.h>
25 #include <unistd.h>
26
27 #include <cctype>
28 #include <cstdio>
29 #include <cstring>
30 #include <ctime>
31 #include <functional>
32 #include <mutex>
33 #include <sstream>
34 #include <string>
35 #include <unordered_map>
36
37 #include "btcore/include/module.h"
38 #include "btif_api.h"
39 #include "btif_common.h"
40 #include "btif_config_cache.h"
41 #include "btif_config_transcode.h"
42 #include "btif_keystore.h"
43 #include "btif_metrics_logging.h"
44 #include "common/address_obfuscator.h"
45 #include "common/metric_id_allocator.h"
46 #include "main/shim/config.h"
47 #include "main/shim/shim.h"
48 #include "osi/include/alarm.h"
49 #include "osi/include/allocator.h"
50 #include "osi/include/compat.h"
51 #include "osi/include/config.h"
52 #include "osi/include/log.h"
53 #include "osi/include/osi.h"
54 #include "osi/include/properties.h"
55 #include "raw_address.h"
56
57 #define BT_CONFIG_SOURCE_TAG_NUM 1010001
58 #define TEMPORARY_SECTION_CAPACITY 10000
59
60 #define INFO_SECTION "Info"
61 #define FILE_TIMESTAMP "TimeCreated"
62 #define FILE_SOURCE "FileSource"
63 #define TIME_STRING_LENGTH sizeof("YYYY-MM-DD HH:MM:SS")
64 #define DISABLED "disabled"
65 static const char* TIME_STRING_FORMAT = "%Y-%m-%d %H:%M:%S";
66
67 #define BT_CONFIG_METRICS_SECTION "Metrics"
68 #define BT_CONFIG_METRICS_SALT_256BIT "Salt256Bit"
69 #define BT_CONFIG_METRICS_ID_KEY "MetricsId"
70
71 using bluetooth::bluetooth_keystore::BluetoothKeystoreInterface;
72 using bluetooth::common::AddressObfuscator;
73 using bluetooth::common::MetricIdAllocator;
74
75 // TODO(armansito): Find a better way than searching by a hardcoded path.
76 #if defined(OS_GENERIC)
77 static const char* CONFIG_FILE_PATH = "bt_config.conf";
78 static const char* CONFIG_BACKUP_PATH = "bt_config.bak";
79 static const char* CONFIG_LEGACY_FILE_PATH = "bt_config.xml";
80 #else // !defined(OS_GENERIC)
81 static const char* CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf";
82 static const char* CONFIG_BACKUP_PATH = "/data/misc/bluedroid/bt_config.bak";
83 static const char* CONFIG_LEGACY_FILE_PATH =
84 "/data/misc/bluedroid/bt_config.xml";
85 #endif // defined(OS_GENERIC)
86 static const uint64_t CONFIG_SETTLE_PERIOD_MS = 3000;
87
88 static void timer_config_save_cb(void* data);
89 static void btif_config_write(uint16_t event, char* p_param);
90 static bool is_factory_reset(void);
91 static void delete_config_files(void);
92 static std::unique_ptr<config_t> btif_config_open(const char* filename);
93
94 // Key attestation
config_checksum_pass(int check_bit)95 static bool config_checksum_pass(int check_bit) {
96 return ((get_common_criteria_config_compare_result() & check_bit) ==
97 check_bit);
98 }
99 static bool btif_in_encrypt_key_name_list(std::string key);
100
101 static const int CONFIG_FILE_COMPARE_PASS = 1;
102 static const int CONFIG_BACKUP_COMPARE_PASS = 2;
103 static const std::string ENCRYPTED_STR = "encrypted";
104 static const std::string CONFIG_FILE_PREFIX = "bt_config-origin";
105 static const std::string CONFIG_FILE_HASH = "hash";
106 static const int ENCRYPT_KEY_NAME_LIST_SIZE = 7;
107 static const std::string encrypt_key_name_list[] = {
108 "LinkKey", "LE_KEY_PENC", "LE_KEY_PID", "LE_KEY_LID",
109 "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK"};
110
111 static enum ConfigSource {
112 NOT_LOADED,
113 ORIGINAL,
114 BACKUP,
115 LEGACY,
116 NEW_FILE,
117 RESET
118 } btif_config_source = NOT_LOADED;
119
120 static char btif_config_time_created[TIME_STRING_LENGTH];
121
get_bluetooth_keystore_interface()122 static BluetoothKeystoreInterface* get_bluetooth_keystore_interface() {
123 return bluetooth::bluetooth_keystore::getBluetoothKeystoreInterface();
124 }
125
126 // TODO(zachoverflow): Move these two functions out, because they are too
127 // specific for this file
128 // {grumpy-cat/no, monty-python/you-make-me-sad}
btif_get_device_type(const RawAddress & bda,int * p_device_type)129 bool btif_get_device_type(const RawAddress& bda, int* p_device_type) {
130 if (p_device_type == NULL) return false;
131
132 std::string addrstr = bda.ToString();
133 const char* bd_addr_str = addrstr.c_str();
134
135 if (!btif_config_get_int(bd_addr_str, "DevType", p_device_type)) return false;
136
137 LOG_INFO("Device [%s] device type %d", bd_addr_str, *p_device_type);
138 return true;
139 }
140
btif_get_address_type(const RawAddress & bda,tBLE_ADDR_TYPE * p_addr_type)141 bool btif_get_address_type(const RawAddress& bda, tBLE_ADDR_TYPE* p_addr_type) {
142 if (p_addr_type == NULL) return false;
143
144 std::string addrstr = bda.ToString();
145 const char* bd_addr_str = addrstr.c_str();
146
147 int val = 0;
148 if (!btif_config_get_int(bd_addr_str, "AddrType", &val)) return false;
149 *p_addr_type = static_cast<tBLE_ADDR_TYPE>(val);
150
151 LOG_DEBUG("Device [%s] address type %s", bd_addr_str,
152 AddressTypeText(*p_addr_type).c_str());
153 return true;
154 }
155
156 /**
157 * Read metrics salt from config file, if salt is invalid or does not exist,
158 * generate new one and save it to config
159 */
read_or_set_metrics_salt()160 static void read_or_set_metrics_salt() {
161 AddressObfuscator::Octet32 metrics_salt = {};
162 size_t metrics_salt_length = metrics_salt.size();
163 if (!btif_config_get_bin(BT_CONFIG_METRICS_SECTION,
164 BT_CONFIG_METRICS_SALT_256BIT, metrics_salt.data(),
165 &metrics_salt_length)) {
166 LOG(WARNING) << __func__ << ": Failed to read metrics salt from config";
167 // Invalidate salt
168 metrics_salt.fill(0);
169 }
170 if (metrics_salt_length != metrics_salt.size()) {
171 LOG(ERROR) << __func__ << ": Metrics salt length incorrect, "
172 << metrics_salt_length << " instead of " << metrics_salt.size();
173 // Invalidate salt
174 metrics_salt.fill(0);
175 }
176 if (!AddressObfuscator::IsSaltValid(metrics_salt)) {
177 LOG(INFO) << __func__ << ": Metrics salt is not invalid, creating new one";
178 if (RAND_bytes(metrics_salt.data(), metrics_salt.size()) != 1) {
179 LOG(FATAL) << __func__ << "Failed to generate salt for metrics";
180 }
181 if (!btif_config_set_bin(BT_CONFIG_METRICS_SECTION,
182 BT_CONFIG_METRICS_SALT_256BIT, metrics_salt.data(),
183 metrics_salt.size())) {
184 LOG(FATAL) << __func__ << "Failed to write metrics salt to config";
185 }
186 }
187 AddressObfuscator::GetInstance()->Initialize(metrics_salt);
188 }
189
190 /**
191 * Initialize metric id allocator by reading metric_id from config by mac
192 * address. If there is no metric id for a mac address, then allocate it a new
193 * metric id.
194 */
init_metric_id_allocator()195 static void init_metric_id_allocator() {
196 std::unordered_map<RawAddress, int> paired_device_map;
197
198 // When user update the system, there will be devices paired with older
199 // version of android without a metric id.
200 std::vector<RawAddress> addresses_without_id;
201
202 for (const auto& mac_address : btif_config_get_paired_devices()) {
203 auto addr_str = mac_address.ToString();
204 // if the section name is a mac address
205 bool is_valid_id_found = false;
206 if (btif_config_exist(addr_str, BT_CONFIG_METRICS_ID_KEY)) {
207 // there is one metric id under this mac_address
208 int id = 0;
209 btif_config_get_int(addr_str, BT_CONFIG_METRICS_ID_KEY, &id);
210 if (is_valid_id_from_metric_id_allocator(id)) {
211 paired_device_map[mac_address] = id;
212 is_valid_id_found = true;
213 }
214 }
215 if (!is_valid_id_found) {
216 addresses_without_id.push_back(mac_address);
217 }
218 }
219
220 // Initialize MetricIdAllocator
221 MetricIdAllocator::Callback save_device_callback =
222 [](const RawAddress& address, const int id) {
223 return btif_config_set_int(address.ToString(), BT_CONFIG_METRICS_ID_KEY,
224 id);
225 };
226 MetricIdAllocator::Callback forget_device_callback =
227 [](const RawAddress& address, const int id) {
228 return btif_config_remove(address.ToString(), BT_CONFIG_METRICS_ID_KEY);
229 };
230 if (!init_metric_id_allocator(paired_device_map,
231 std::move(save_device_callback),
232 std::move(forget_device_callback))) {
233 LOG(FATAL) << __func__ << "Failed to initialize MetricIdAllocator";
234 }
235
236 // Add device_without_id
237 for (auto& address : addresses_without_id) {
238 allocate_metric_id_from_metric_id_allocator(address);
239 save_metric_id_from_metric_id_allocator(address);
240 }
241 }
242
243 static std::recursive_mutex config_lock; // protects operations on |config|.
244 static alarm_t* config_timer;
245
246 // limited btif config cache capacity
247 static BtifConfigCache btif_config_cache(TEMPORARY_SECTION_CAPACITY);
248
249 // Module lifecycle functions
250
init(void)251 static future_t* init(void) {
252 if (bluetooth::shim::is_any_gd_enabled()) {
253 CHECK(bluetooth::shim::is_gd_stack_started_up());
254 // TODO (b/158035889) Migrate metrics module to GD
255 read_or_set_metrics_salt();
256 init_metric_id_allocator();
257 return future_new_immediate(FUTURE_SUCCESS);
258 }
259 std::unique_lock<std::recursive_mutex> lock(config_lock);
260 std::unique_ptr<config_t> config;
261
262 if (is_factory_reset()) delete_config_files();
263
264 std::string file_source;
265
266 if (config_checksum_pass(CONFIG_FILE_COMPARE_PASS)) {
267 config = btif_config_open(CONFIG_FILE_PATH);
268 btif_config_source = ORIGINAL;
269 }
270 if (!config) {
271 LOG_WARN("%s unable to load config file: %s; using backup.", __func__,
272 CONFIG_FILE_PATH);
273 if (config_checksum_pass(CONFIG_BACKUP_COMPARE_PASS)) {
274 config = btif_config_open(CONFIG_BACKUP_PATH);
275 btif_config_source = BACKUP;
276 file_source = "Backup";
277 }
278 }
279 if (!config) {
280 LOG_WARN("%s unable to load backup; attempting to transcode legacy file.",
281 __func__);
282 config = btif_config_transcode(CONFIG_LEGACY_FILE_PATH);
283 btif_config_source = LEGACY;
284 file_source = "Legacy";
285 }
286 if (!config) {
287 LOG_ERROR("%s unable to transcode legacy file; creating empty config.",
288 __func__);
289 config = config_new_empty();
290 btif_config_source = NEW_FILE;
291 file_source = "Empty";
292 }
293
294 // move persistent config data from btif_config file to btif config cache
295 btif_config_cache.Init(std::move(config));
296
297 if (!file_source.empty()) {
298 btif_config_cache.SetString(INFO_SECTION, FILE_SOURCE, file_source);
299 }
300
301 // Cleanup temporary pairings if we have left guest mode
302 if (!is_restricted_mode()) {
303 btif_config_cache.RemovePersistentSectionsWithKey("Restricted");
304 }
305
306 // Read or set config file creation timestamp
307 auto time_str = btif_config_cache.GetString(INFO_SECTION, FILE_TIMESTAMP);
308 if (!time_str) {
309 time_t current_time = time(NULL);
310 struct tm* time_created = localtime(¤t_time);
311 strftime(btif_config_time_created, TIME_STRING_LENGTH, TIME_STRING_FORMAT,
312 time_created);
313 btif_config_cache.SetString(INFO_SECTION, FILE_TIMESTAMP,
314 btif_config_time_created);
315 } else {
316 strlcpy(btif_config_time_created, time_str->c_str(), TIME_STRING_LENGTH);
317 }
318
319 // Read or set metrics 256 bit hashing salt
320 read_or_set_metrics_salt();
321
322 // Initialize MetricIdAllocator
323 init_metric_id_allocator();
324
325 // TODO(sharvil): use a non-wake alarm for this once we have
326 // API support for it. There's no need to wake the system to
327 // write back to disk.
328 config_timer = alarm_new("btif.config");
329 if (!config_timer) {
330 LOG_ERROR("%s unable to create alarm.", __func__);
331 goto error;
332 }
333
334 LOG_EVENT_INT(BT_CONFIG_SOURCE_TAG_NUM, btif_config_source);
335
336 return future_new_immediate(FUTURE_SUCCESS);
337
338 error:
339 alarm_free(config_timer);
340 config.reset();
341 btif_config_cache.Clear();
342 config_timer = NULL;
343 btif_config_source = NOT_LOADED;
344 return future_new_immediate(FUTURE_FAIL);
345 }
346
btif_config_open(const char * filename)347 static std::unique_ptr<config_t> btif_config_open(const char* filename) {
348 std::unique_ptr<config_t> config = config_new(filename);
349 if (!config) return nullptr;
350
351 if (!config_has_section(*config, "Adapter")) {
352 LOG_ERROR("Config is missing adapter section");
353 return nullptr;
354 }
355
356 return config;
357 }
358
shut_down(void)359 static future_t* shut_down(void) {
360 btif_config_flush();
361 return future_new_immediate(FUTURE_SUCCESS);
362 }
363
clean_up(void)364 static future_t* clean_up(void) {
365 if (bluetooth::shim::is_any_gd_enabled()) {
366 CHECK(bluetooth::shim::is_gd_stack_started_up());
367 // GD storage module cleanup by itself
368 std::unique_lock<std::recursive_mutex> lock(config_lock);
369 close_metric_id_allocator();
370 return future_new_immediate(FUTURE_SUCCESS);
371 }
372 btif_config_flush();
373
374 alarm_free(config_timer);
375 config_timer = NULL;
376
377 std::unique_lock<std::recursive_mutex> lock(config_lock);
378 get_bluetooth_keystore_interface()->clear_map();
379 close_metric_id_allocator();
380 btif_config_cache.Clear();
381 return future_new_immediate(FUTURE_SUCCESS);
382 }
383
384 EXPORT_SYMBOL module_t btif_config_module = {.name = BTIF_CONFIG_MODULE,
385 .init = init,
386 .start_up = NULL,
387 .shut_down = shut_down,
388 .clean_up = clean_up};
389
btif_config_exist(const std::string & section,const std::string & key)390 bool btif_config_exist(const std::string& section, const std::string& key) {
391 if (bluetooth::shim::is_any_gd_enabled()) {
392 CHECK(bluetooth::shim::is_gd_stack_started_up());
393 return bluetooth::shim::BtifConfigInterface::HasProperty(section, key);
394 }
395 std::unique_lock<std::recursive_mutex> lock(config_lock);
396 return btif_config_cache.HasKey(section, key);
397 }
398
btif_config_get_int(const std::string & section,const std::string & key,int * value)399 bool btif_config_get_int(const std::string& section, const std::string& key,
400 int* value) {
401 if (bluetooth::shim::is_any_gd_enabled()) {
402 CHECK(bluetooth::shim::is_gd_stack_started_up());
403 return bluetooth::shim::BtifConfigInterface::GetInt(section, key, value);
404 }
405 CHECK(value != NULL);
406 std::unique_lock<std::recursive_mutex> lock(config_lock);
407 auto ret = btif_config_cache.GetInt(section, key);
408 if (!ret) {
409 return false;
410 }
411 *value = *ret;
412 return true;
413 }
414
btif_config_set_int(const std::string & section,const std::string & key,int value)415 bool btif_config_set_int(const std::string& section, const std::string& key,
416 int value) {
417 if (bluetooth::shim::is_any_gd_enabled()) {
418 CHECK(bluetooth::shim::is_gd_stack_started_up());
419 return bluetooth::shim::BtifConfigInterface::SetInt(section, key, value);
420 }
421 std::unique_lock<std::recursive_mutex> lock(config_lock);
422 btif_config_cache.SetInt(section, key, value);
423 return true;
424 }
425
btif_config_get_uint64(const std::string & section,const std::string & key,uint64_t * value)426 bool btif_config_get_uint64(const std::string& section, const std::string& key,
427 uint64_t* value) {
428 if (bluetooth::shim::is_any_gd_enabled()) {
429 CHECK(bluetooth::shim::is_gd_stack_started_up());
430 return bluetooth::shim::BtifConfigInterface::GetUint64(section, key, value);
431 }
432 CHECK(value != NULL);
433 std::unique_lock<std::recursive_mutex> lock(config_lock);
434 auto ret = btif_config_cache.GetUint64(section, key);
435 if (!ret) {
436 return false;
437 }
438 *value = *ret;
439 return true;
440 }
441
btif_config_set_uint64(const std::string & section,const std::string & key,uint64_t value)442 bool btif_config_set_uint64(const std::string& section, const std::string& key,
443 uint64_t value) {
444 if (bluetooth::shim::is_any_gd_enabled()) {
445 CHECK(bluetooth::shim::is_gd_stack_started_up());
446 return bluetooth::shim::BtifConfigInterface::SetUint64(section, key, value);
447 }
448 std::unique_lock<std::recursive_mutex> lock(config_lock);
449 btif_config_cache.SetUint64(section, key, value);
450 return true;
451 }
452
453 /*******************************************************************************
454 *
455 * Function btif_config_get_str
456 *
457 * Description Get the string value associated with a particular section
458 * and key.
459 *
460 * section : The section name (i.e "Adapter")
461 * key : The key name (i.e "Address")
462 * value : A pointer to a buffer where we will store the value
463 * size_bytes : The size of the buffer we have available to
464 * write the value into. Will be updated upon
465 * returning to contain the number of bytes
466 * written.
467 *
468 * Returns True if a value was found, False otherwise.
469 *
470 ******************************************************************************/
471
btif_config_get_str(const std::string & section,const std::string & key,char * value,int * size_bytes)472 bool btif_config_get_str(const std::string& section, const std::string& key,
473 char* value, int* size_bytes) {
474 if (bluetooth::shim::is_any_gd_enabled()) {
475 CHECK(bluetooth::shim::is_gd_stack_started_up());
476 return bluetooth::shim::BtifConfigInterface::GetStr(section, key, value,
477 size_bytes);
478 }
479 CHECK(value != NULL);
480 CHECK(size_bytes != NULL);
481
482 {
483 std::unique_lock<std::recursive_mutex> lock(config_lock);
484 auto stored_value = btif_config_cache.GetString(section, key);
485 if (!stored_value) return false;
486 strlcpy(value, stored_value->c_str(), *size_bytes);
487 }
488 *size_bytes = strlen(value) + 1;
489 return true;
490 }
491
btif_config_set_str(const std::string & section,const std::string & key,const std::string & value)492 bool btif_config_set_str(const std::string& section, const std::string& key,
493 const std::string& value) {
494 if (bluetooth::shim::is_any_gd_enabled()) {
495 CHECK(bluetooth::shim::is_gd_stack_started_up());
496 return bluetooth::shim::BtifConfigInterface::SetStr(section, key, value);
497 }
498 std::unique_lock<std::recursive_mutex> lock(config_lock);
499 btif_config_cache.SetString(section, key, value);
500 return true;
501 }
502
btif_in_encrypt_key_name_list(std::string key)503 static bool btif_in_encrypt_key_name_list(std::string key) {
504 return std::find(encrypt_key_name_list,
505 encrypt_key_name_list + ENCRYPT_KEY_NAME_LIST_SIZE,
506 key) != (encrypt_key_name_list + ENCRYPT_KEY_NAME_LIST_SIZE);
507 }
508
btif_config_get_bin(const std::string & section,const std::string & key,uint8_t * value,size_t * length)509 bool btif_config_get_bin(const std::string& section, const std::string& key,
510 uint8_t* value, size_t* length) {
511 if (bluetooth::shim::is_any_gd_enabled()) {
512 CHECK(bluetooth::shim::is_gd_stack_started_up());
513 return bluetooth::shim::BtifConfigInterface::GetBin(section, key, value,
514 length);
515 }
516 CHECK(value != NULL);
517 CHECK(length != NULL);
518
519 std::unique_lock<std::recursive_mutex> lock(config_lock);
520 const std::string* value_str;
521 auto value_str_from_config = btif_config_cache.GetString(section, key);
522
523 if (!value_str_from_config) {
524 VLOG(1) << __func__ << ": cannot find string for section " << section
525 << ", key " << key;
526 return false;
527 }
528
529 bool in_encrypt_key_name_list = btif_in_encrypt_key_name_list(key);
530 bool is_key_encrypted = *value_str_from_config == ENCRYPTED_STR;
531 std::string string;
532
533 if (!value_str_from_config->empty() && in_encrypt_key_name_list &&
534 is_key_encrypted) {
535 string = get_bluetooth_keystore_interface()->get_key(section + "-" + key);
536 value_str = &string;
537 } else {
538 value_str = &value_str_from_config.value();
539 }
540
541 size_t value_len = value_str->length();
542 if ((value_len % 2) != 0 || *length < (value_len / 2)) {
543 LOG(WARNING) << ": value size not divisible by 2, size is " << value_len;
544 return false;
545 }
546
547 for (size_t i = 0; i < value_len; ++i)
548 if (!isxdigit(value_str->c_str()[i])) {
549 LOG(WARNING) << ": value is not hex digit";
550 return false;
551 }
552
553 const char* ptr = value_str->c_str();
554 for (*length = 0; *ptr; ptr += 2, *length += 1) {
555 sscanf(ptr, "%02hhx", &value[*length]);
556 }
557
558 if (is_common_criteria_mode()) {
559 if (!value_str_from_config->empty() && in_encrypt_key_name_list &&
560 !is_key_encrypted) {
561 get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
562 section + "-" + key, *value_str_from_config);
563 btif_config_cache.SetString(section, key, ENCRYPTED_STR);
564 }
565 } else {
566 if (in_encrypt_key_name_list && is_key_encrypted) {
567 btif_config_cache.SetString(section, key, *value_str);
568 }
569 }
570
571 return true;
572 }
573
btif_config_get_bin_length(const std::string & section,const std::string & key)574 size_t btif_config_get_bin_length(const std::string& section,
575 const std::string& key) {
576 if (bluetooth::shim::is_any_gd_enabled()) {
577 CHECK(bluetooth::shim::is_gd_stack_started_up());
578 return bluetooth::shim::BtifConfigInterface::GetBinLength(section, key);
579 }
580 std::unique_lock<std::recursive_mutex> lock(config_lock);
581 auto value_str = btif_config_cache.GetString(section, key);
582 if (!value_str) return 0;
583 size_t value_len = value_str->length();
584 return ((value_len % 2) != 0) ? 0 : (value_len / 2);
585 }
586
btif_config_set_bin(const std::string & section,const std::string & key,const uint8_t * value,size_t length)587 bool btif_config_set_bin(const std::string& section, const std::string& key,
588 const uint8_t* value, size_t length) {
589 if (bluetooth::shim::is_any_gd_enabled()) {
590 CHECK(bluetooth::shim::is_gd_stack_started_up());
591 return bluetooth::shim::BtifConfigInterface::SetBin(section, key, value,
592 length);
593 }
594 const char* lookup = "0123456789abcdef";
595 if (length > 0) CHECK(value != NULL);
596
597 size_t max_value = ((size_t)-1);
598 if (((max_value - 1) / 2) < length) {
599 LOG(ERROR) << __func__ << ": length too long";
600 return false;
601 }
602
603 char* str = (char*)osi_calloc(length * 2 + 1);
604
605 for (size_t i = 0; i < length; ++i) {
606 str[(i * 2) + 0] = lookup[(value[i] >> 4) & 0x0F];
607 str[(i * 2) + 1] = lookup[value[i] & 0x0F];
608 }
609
610 std::string value_str;
611 if ((length > 0) && is_common_criteria_mode() &&
612 btif_in_encrypt_key_name_list(key)) {
613 get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
614 section + "-" + key, str);
615 value_str = ENCRYPTED_STR;
616 } else {
617 value_str = str;
618 }
619
620 {
621 std::unique_lock<std::recursive_mutex> lock(config_lock);
622 btif_config_cache.SetString(section, key, value_str);
623 }
624
625 osi_free(str);
626 return true;
627 }
628
btif_config_get_paired_devices()629 std::vector<RawAddress> btif_config_get_paired_devices() {
630 std::vector<std::string> names;
631 if (bluetooth::shim::is_any_gd_enabled()) {
632 CHECK(bluetooth::shim::is_gd_stack_started_up());
633 names = bluetooth::shim::BtifConfigInterface::GetPersistentDevices();
634 } else {
635 std::unique_lock<std::recursive_mutex> lock(config_lock);
636 names = btif_config_cache.GetPersistentSectionNames();
637 }
638 std::vector<RawAddress> result;
639 result.reserve(names.size());
640 for (const auto& name : names) {
641 RawAddress addr = {};
642 // Gather up known devices from configuration section names
643 if (RawAddress::FromString(name, addr)) {
644 result.emplace_back(addr);
645 }
646 }
647 return result;
648 }
649
btif_config_remove(const std::string & section,const std::string & key)650 bool btif_config_remove(const std::string& section, const std::string& key) {
651 if (bluetooth::shim::is_any_gd_enabled()) {
652 CHECK(bluetooth::shim::is_gd_stack_started_up());
653 return bluetooth::shim::BtifConfigInterface::RemoveProperty(section, key);
654 }
655 if (is_common_criteria_mode() && btif_in_encrypt_key_name_list(key)) {
656 get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
657 section + "-" + key, "");
658 }
659 std::unique_lock<std::recursive_mutex> lock(config_lock);
660 return btif_config_cache.RemoveKey(section, key);
661 }
662
btif_config_save(void)663 void btif_config_save(void) {
664 if (bluetooth::shim::is_any_gd_enabled()) {
665 CHECK(bluetooth::shim::is_gd_stack_started_up());
666 bluetooth::shim::BtifConfigInterface::Save();
667 return;
668 }
669 CHECK(config_timer != NULL);
670
671 alarm_set(config_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save_cb, NULL);
672 }
673
btif_config_flush(void)674 void btif_config_flush(void) {
675 if (bluetooth::shim::is_any_gd_enabled()) {
676 CHECK(bluetooth::shim::is_gd_stack_started_up());
677 bluetooth::shim::BtifConfigInterface::Flush();
678 return;
679 }
680 CHECK(config_timer != NULL);
681
682 alarm_cancel(config_timer);
683 btif_config_write(0, NULL);
684 }
685
btif_config_clear(void)686 bool btif_config_clear(void) {
687 if (bluetooth::shim::is_any_gd_enabled()) {
688 CHECK(bluetooth::shim::is_gd_stack_started_up());
689 bluetooth::shim::BtifConfigInterface::Clear();
690 bluetooth::shim::BtifConfigInterface::Save();
691 return true;
692 }
693 CHECK(config_timer != NULL);
694
695 alarm_cancel(config_timer);
696
697 std::unique_lock<std::recursive_mutex> lock(config_lock);
698
699 btif_config_cache.Clear();
700 bool ret =
701 config_save(btif_config_cache.PersistentSectionCopy(), CONFIG_FILE_PATH);
702 btif_config_source = RESET;
703
704 return ret;
705 }
706
timer_config_save_cb(UNUSED_ATTR void * data)707 static void timer_config_save_cb(UNUSED_ATTR void* data) {
708 // Moving file I/O to btif context instead of timer callback because
709 // it usually takes a lot of time to be completed, introducing
710 // delays during A2DP playback causing blips or choppiness.
711 btif_transfer_context(btif_config_write, 0, NULL, 0, NULL);
712 }
713
btif_config_write(UNUSED_ATTR uint16_t event,UNUSED_ATTR char * p_param)714 static void btif_config_write(UNUSED_ATTR uint16_t event,
715 UNUSED_ATTR char* p_param) {
716 CHECK(config_timer != NULL);
717
718 std::unique_lock<std::recursive_mutex> lock(config_lock);
719 rename(CONFIG_FILE_PATH, CONFIG_BACKUP_PATH);
720 config_save(btif_config_cache.PersistentSectionCopy(), CONFIG_FILE_PATH);
721 if (is_common_criteria_mode()) {
722 get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
723 CONFIG_FILE_PREFIX, CONFIG_FILE_HASH);
724 }
725 }
726
btif_debug_config_dump(int fd)727 void btif_debug_config_dump(int fd) {
728 dprintf(fd, "\nBluetooth Config:\n");
729
730 dprintf(fd, " Config Source: ");
731 switch (btif_config_source) {
732 case NOT_LOADED:
733 dprintf(fd, "Not loaded\n");
734 break;
735 case ORIGINAL:
736 dprintf(fd, "Original file\n");
737 break;
738 case BACKUP:
739 dprintf(fd, "Backup file\n");
740 break;
741 case LEGACY:
742 dprintf(fd, "Legacy file\n");
743 break;
744 case NEW_FILE:
745 dprintf(fd, "New file\n");
746 break;
747 case RESET:
748 dprintf(fd, "Reset file\n");
749 break;
750 }
751
752 std::optional<std::string> file_source;
753 if (bluetooth::shim::is_gd_stack_started_up()) {
754 CHECK(bluetooth::shim::is_any_gd_enabled());
755 file_source =
756 bluetooth::shim::BtifConfigInterface::GetStr(INFO_SECTION, FILE_SOURCE);
757 } else {
758 file_source = btif_config_cache.GetString(INFO_SECTION, FILE_SOURCE);
759 }
760 if (!file_source) {
761 file_source.emplace("Original");
762 }
763 auto devices = btif_config_cache.GetPersistentSectionNames();
764 dprintf(fd, " Devices loaded: %zu\n", devices.size());
765 dprintf(fd, " File created/tagged: %s\n", btif_config_time_created);
766 dprintf(fd, " File source: %s\n", file_source->c_str());
767 }
768
is_factory_reset(void)769 static bool is_factory_reset(void) {
770 char factory_reset[PROPERTY_VALUE_MAX] = {0};
771 osi_property_get("persist.bluetooth.factoryreset", factory_reset, "false");
772 return strncmp(factory_reset, "true", 4) == 0;
773 }
774
delete_config_files(void)775 static void delete_config_files(void) {
776 remove(CONFIG_FILE_PATH);
777 remove(CONFIG_BACKUP_PATH);
778 osi_property_set("persist.bluetooth.factoryreset", "false");
779 }
780