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