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