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