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