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 <bluetooth/log.h>
24 #include <openssl/rand.h>
25 #include <unistd.h>
26 
27 #include <cstdio>
28 #include <cstring>
29 #include <ctime>
30 #include <mutex>
31 #include <string>
32 #include <unordered_map>
33 
34 #include "btif_keystore.h"
35 #include "btif_metrics_logging.h"
36 #include "common/address_obfuscator.h"
37 #include "common/metric_id_allocator.h"
38 #include "main/shim/config.h"
39 #include "main/shim/shim.h"
40 #include "storage/config_keys.h"
41 #include "types/raw_address.h"
42 
43 #define TEMPORARY_SECTION_CAPACITY 10000
44 
45 #define INFO_SECTION "Info"
46 #define FILE_TIMESTAMP "TimeCreated"
47 #define FILE_SOURCE "FileSource"
48 #define TIME_STRING_LENGTH sizeof("YYYY-MM-DD HH:MM:SS")
49 #define DISABLED "disabled"
50 
51 using bluetooth::bluetooth_keystore::BluetoothKeystoreInterface;
52 using bluetooth::common::AddressObfuscator;
53 using bluetooth::common::MetricIdAllocator;
54 using namespace bluetooth;
55 
56 // Key attestation
57 static const std::string ENCRYPTED_STR = "encrypted";
58 static const std::string CONFIG_FILE_PREFIX = "bt_config-origin";
59 static const std::string CONFIG_FILE_HASH = "hash";
60 static const std::string encrypt_key_name_list[] = {"LinkKey",     "LE_KEY_PENC",  "LE_KEY_PID",
61                                                     "LE_KEY_LID",  "LE_KEY_PCSRK", "LE_KEY_LENC",
62                                                     "LE_KEY_LCSRK"};
63 
64 /**
65  * Read metrics salt from config file, if salt is invalid or does not exist,
66  * generate new one and save it to config
67  */
read_or_set_metrics_salt()68 static void read_or_set_metrics_salt() {
69   AddressObfuscator::Octet32 metrics_salt = {};
70   size_t metrics_salt_length = metrics_salt.size();
71   if (!btif_config_get_bin(BTIF_STORAGE_SECTION_METRICS, BTIF_STORAGE_KEY_METRICS_SALT_256BIT,
72                            metrics_salt.data(), &metrics_salt_length)) {
73     log::warn("Failed to read metrics salt from config");
74     // Invalidate salt
75     metrics_salt.fill(0);
76   }
77   if (metrics_salt_length != metrics_salt.size()) {
78     log::error("Metrics salt length incorrect, {} instead of {}", metrics_salt_length,
79                metrics_salt.size());
80     // Invalidate salt
81     metrics_salt.fill(0);
82   }
83   if (!AddressObfuscator::IsSaltValid(metrics_salt)) {
84     log::info("Metrics salt is invalid, creating new one");
85     if (RAND_bytes(metrics_salt.data(), metrics_salt.size()) != 1) {
86       log::fatal("Failed to generate salt for metrics");
87     }
88     if (!btif_config_set_bin(BTIF_STORAGE_SECTION_METRICS, BTIF_STORAGE_KEY_METRICS_SALT_256BIT,
89                              metrics_salt.data(), metrics_salt.size())) {
90       log::fatal("Failed to write metrics salt to config");
91     }
92   }
93   AddressObfuscator::GetInstance()->Initialize(metrics_salt);
94 }
95 
96 /**
97  * Initialize metric id allocator by reading metric_id from config by mac
98  * address. If there is no metric id for a mac address, then allocate it a new
99  * metric id.
100  */
init_metric_id_allocator()101 static void init_metric_id_allocator() {
102   std::unordered_map<RawAddress, int> paired_device_map;
103 
104   // When user update the system, there will be devices paired with older
105   // version of android without a metric id.
106   std::vector<RawAddress> addresses_without_id;
107 
108   for (const auto& mac_address : btif_config_get_paired_devices()) {
109     auto addr_str = mac_address.ToString();
110     // if the section name is a mac address
111     bool is_valid_id_found = false;
112     if (btif_config_exist(addr_str, BTIF_STORAGE_KEY_METRICS_ID_KEY)) {
113       // there is one metric id under this mac_address
114       int id = 0;
115       btif_config_get_int(addr_str, BTIF_STORAGE_KEY_METRICS_ID_KEY, &id);
116       if (is_valid_id_from_metric_id_allocator(id)) {
117         paired_device_map[mac_address] = id;
118         is_valid_id_found = true;
119       }
120     }
121     if (!is_valid_id_found) {
122       addresses_without_id.push_back(mac_address);
123     }
124   }
125 
126   // Initialize MetricIdAllocator
127   MetricIdAllocator::Callback save_device_callback = [](const RawAddress& address, const int id) {
128     return btif_config_set_int(address.ToString(), BTIF_STORAGE_KEY_METRICS_ID_KEY, id);
129   };
130   MetricIdAllocator::Callback forget_device_callback = [](const RawAddress& address,
131                                                           const int /* id */) {
132     return btif_config_remove(address.ToString(), BTIF_STORAGE_KEY_METRICS_ID_KEY);
133   };
134   if (!init_metric_id_allocator(paired_device_map, std::move(save_device_callback),
135                                 std::move(forget_device_callback))) {
136     log::fatal("Failed to initialize MetricIdAllocator");
137   }
138 
139   // Add device_without_id
140   for (auto& address : addresses_without_id) {
141     allocate_metric_id_from_metric_id_allocator(address);
142     save_metric_id_from_metric_id_allocator(address);
143   }
144 }
145 
146 static std::recursive_mutex config_lock;  // protects operations on |config|.
147 
148 // Module lifecycle functions
149 
init(void)150 static future_t* init(void) {
151   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
152                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
153   // TODO (b/158035889) Migrate metrics module to GD
154   read_or_set_metrics_salt();
155   init_metric_id_allocator();
156   return future_new_immediate(FUTURE_SUCCESS);
157 }
158 
shut_down(void)159 static future_t* shut_down(void) { return future_new_immediate(FUTURE_SUCCESS); }
160 
clean_up(void)161 static future_t* clean_up(void) {
162   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
163                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
164   // GD storage module cleanup by itself
165   std::unique_lock<std::recursive_mutex> lock(config_lock);
166   close_metric_id_allocator();
167   return future_new_immediate(FUTURE_SUCCESS);
168 }
169 
170 EXPORT_SYMBOL module_t btif_config_module = {.name = BTIF_CONFIG_MODULE,
171                                              .init = init,
172                                              .start_up = NULL,
173                                              .shut_down = shut_down,
174                                              .clean_up = clean_up};
175 
btif_get_device_clockoffset(const RawAddress & bda,int * p_clock_offset)176 bool btif_get_device_clockoffset(const RawAddress& bda, int* p_clock_offset) {
177   if (p_clock_offset == NULL) {
178     return false;
179   }
180 
181   std::string addrstr = bda.ToString();
182   const char* bd_addr_str = addrstr.c_str();
183 
184   if (!btif_config_get_int(bd_addr_str, BTIF_STORAGE_KEY_CLOCK_OFFSET, p_clock_offset)) {
185     return false;
186   }
187 
188   log::debug("Device [{}] clock_offset {}", bda, *p_clock_offset);
189   return true;
190 }
191 
btif_set_device_clockoffset(const RawAddress & bda,int clock_offset)192 bool btif_set_device_clockoffset(const RawAddress& bda, int clock_offset) {
193   std::string addrstr = bda.ToString();
194   const char* bd_addr_str = addrstr.c_str();
195 
196   if (!btif_config_set_int(bd_addr_str, BTIF_STORAGE_KEY_CLOCK_OFFSET, clock_offset)) {
197     return false;
198   }
199 
200   log::debug("Device [{}] clock_offset {}", bda, clock_offset);
201   return true;
202 }
203 
btif_config_exist(const std::string & section,const std::string & key)204 bool btif_config_exist(const std::string& section, const std::string& key) {
205   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
206                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
207   return bluetooth::shim::BtifConfigInterface::HasProperty(section, key);
208 }
209 
btif_config_get_int(const std::string & section,const std::string & key,int * value)210 bool btif_config_get_int(const std::string& section, const std::string& key, int* value) {
211   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
212                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
213   return bluetooth::shim::BtifConfigInterface::GetInt(section, key, value);
214 }
215 
btif_config_set_int(const std::string & section,const std::string & key,int value)216 bool btif_config_set_int(const std::string& section, const std::string& key, int value) {
217   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
218                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
219   return bluetooth::shim::BtifConfigInterface::SetInt(section, key, value);
220 }
221 
btif_config_get_uint64(const std::string & section,const std::string & key,uint64_t * value)222 bool btif_config_get_uint64(const std::string& section, const std::string& key, uint64_t* value) {
223   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
224                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
225   return bluetooth::shim::BtifConfigInterface::GetUint64(section, key, value);
226 }
227 
btif_config_set_uint64(const std::string & section,const std::string & key,uint64_t value)228 bool btif_config_set_uint64(const std::string& section, const std::string& key, uint64_t value) {
229   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
230                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
231   return bluetooth::shim::BtifConfigInterface::SetUint64(section, key, value);
232 }
233 
234 /*******************************************************************************
235  *
236  * Function         btif_config_get_str
237  *
238  * Description      Get the string value associated with a particular section
239  *                  and key.
240  *
241  *                  section : The section name (i.e "Adapter")
242  *                  key : The key name (i.e "Address")
243  *                  value : A pointer to a buffer where we will store the value
244  *                  size_bytes : The size of the buffer we have available to
245  *                               write the value into. Will be updated upon
246  *                               returning to contain the number of bytes
247  *                               written.
248  *
249  * Returns          True if a value was found, False otherwise.
250  *
251  ******************************************************************************/
252 
btif_config_get_str(const std::string & section,const std::string & key,char * value,int * size_bytes)253 bool btif_config_get_str(const std::string& section, const std::string& key, char* value,
254                          int* size_bytes) {
255   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
256                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
257   return bluetooth::shim::BtifConfigInterface::GetStr(section, key, value, size_bytes);
258 }
259 
btif_config_set_str(const std::string & section,const std::string & key,const std::string & value)260 bool btif_config_set_str(const std::string& section, const std::string& key,
261                          const std::string& value) {
262   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
263                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
264   return bluetooth::shim::BtifConfigInterface::SetStr(section, key, value);
265 }
266 
btif_config_get_bin(const std::string & section,const std::string & key,uint8_t * value,size_t * length)267 bool btif_config_get_bin(const std::string& section, const std::string& key, uint8_t* value,
268                          size_t* length) {
269   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
270                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
271   return bluetooth::shim::BtifConfigInterface::GetBin(section, key, value, length);
272 }
273 
btif_config_get_bin_length(const std::string & section,const std::string & key)274 size_t btif_config_get_bin_length(const std::string& section, const std::string& key) {
275   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
276                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
277   return bluetooth::shim::BtifConfigInterface::GetBinLength(section, key);
278 }
279 
btif_config_set_bin(const std::string & section,const std::string & key,const uint8_t * value,size_t length)280 bool btif_config_set_bin(const std::string& section, const std::string& key, const uint8_t* value,
281                          size_t length) {
282   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
283                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
284   return bluetooth::shim::BtifConfigInterface::SetBin(section, key, value, length);
285 }
286 
btif_config_get_paired_devices()287 std::vector<RawAddress> btif_config_get_paired_devices() {
288   std::vector<std::string> names;
289   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
290                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
291   names = bluetooth::shim::BtifConfigInterface::GetPersistentDevices();
292 
293   std::vector<RawAddress> result;
294   result.reserve(names.size());
295   for (const auto& name : names) {
296     RawAddress addr = {};
297     // Gather up known devices from configuration section names
298     if (RawAddress::FromString(name, addr)) {
299       result.emplace_back(addr);
300     }
301   }
302   return result;
303 }
304 
btif_config_remove(const std::string & section,const std::string & key)305 bool btif_config_remove(const std::string& section, const std::string& key) {
306   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
307                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
308   return bluetooth::shim::BtifConfigInterface::RemoveProperty(section, key);
309 }
310 
btif_config_remove_device(const std::string & section)311 void btif_config_remove_device(const std::string& section) {
312   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
313                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
314   bluetooth::shim::BtifConfigInterface::RemoveSection(section);
315 }
316 
btif_config_remove_device_with_key(const std::string & key)317 void btif_config_remove_device_with_key(const std::string& key) {
318   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
319                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
320   bluetooth::shim::BtifConfigInterface::RemoveSectionWithProperty(key);
321 }
322 
btif_config_clear(void)323 bool btif_config_clear(void) {
324   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
325                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
326   bluetooth::shim::BtifConfigInterface::Clear();
327   return true;
328 }
329