#include <string>
#include <unordered_map>
+#include <btif_keystore.h>
#include "bt_types.h"
#include "btcore/include/module.h"
#include "btif_api.h"
#define BT_CONFIG_METRICS_SALT_256BIT "Salt256Bit"
#define BT_CONFIG_METRICS_ID_KEY "MetricsId"
+using bluetooth::bluetooth_keystore::BluetoothKeystoreInterface;
using bluetooth::common::AddressObfuscator;
using bluetooth::common::MetricIdAllocator;
static void btif_config_remove_restricted(config_t* config);
static std::unique_ptr<config_t> btif_config_open(const char* filename);
+// Key attestation
+static bool config_checksum_pass(int check_bit) {
+ return ((get_niap_config_compare_result() & check_bit) == check_bit);
+}
+static bool btif_is_niap_mode() {
+ return getuid() == AID_BLUETOOTH && is_niap_mode();
+}
+static bool btif_in_encrypt_key_name_list(std::string key);
+
+static const int CONFIG_FILE_COMPARE_PASS = 1;
+static const int CONFIG_BACKUP_COMPARE_PASS = 2;
+static const std::string ENCRYPTED_STR = "encrypted";
+static const std::string CONFIG_FILE_PREFIX = "bt_config-origin";
+static const std::string CONFIG_FILE_HASH = "hash";
+static const int ENCRYPT_KEY_NAME_LIST_SIZE = 7;
+static const std::string encrypt_key_name_list[] = {
+ "LinkKey", "LE_KEY_PENC", "LE_KEY_PID", "LE_KEY_LID",
+ "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK"};
+
static enum ConfigSource {
NOT_LOADED,
ORIGINAL,
}
}
+static BluetoothKeystoreInterface* get_bluetooth_keystore_interface() {
+ return bluetooth::bluetooth_keystore::getBluetoothKeystoreInterface();
+}
+
// TODO(zachoverflow): Move these two functions out, because they are too
// specific for this file
// {grumpy-cat/no, monty-python/you-make-me-sad}
std::string file_source;
- config = btif_config_open(CONFIG_FILE_PATH);
- btif_config_source = ORIGINAL;
+ if (config_checksum_pass(CONFIG_FILE_COMPARE_PASS)) {
+ config = btif_config_open(CONFIG_FILE_PATH);
+ btif_config_source = ORIGINAL;
+ }
if (!config) {
LOG_WARN(LOG_TAG, "%s unable to load config file: %s; using backup.",
__func__, CONFIG_FILE_PATH);
- config = btif_config_open(CONFIG_BACKUP_PATH);
- btif_config_source = BACKUP;
- file_source = "Backup";
+ if (config_checksum_pass(CONFIG_BACKUP_COMPARE_PASS)) {
+ config = btif_config_open(CONFIG_BACKUP_PATH);
+ btif_config_source = BACKUP;
+ file_source = "Backup";
+ }
}
if (!config) {
LOG_WARN(LOG_TAG,
return true;
}
+static bool btif_in_encrypt_key_name_list(std::string key) {
+ return std::find(encrypt_key_name_list,
+ encrypt_key_name_list + ENCRYPT_KEY_NAME_LIST_SIZE,
+ key) != (encrypt_key_name_list + ENCRYPT_KEY_NAME_LIST_SIZE);
+}
+
bool btif_config_get_bin(const std::string& section, const std::string& key,
uint8_t* value, size_t* length) {
CHECK(config != NULL);
CHECK(length != NULL);
std::unique_lock<std::recursive_mutex> lock(config_lock);
- const std::string* value_str =
- storage_config_get_interface()->config_get_string(*config, section, key,
- NULL);
+ const std::string* value_str;
+ const std::string* value_str_from_config =
+ config_get_string(*config, section, key, NULL);
- if (!value_str) {
+ if (!value_str_from_config) {
VLOG(1) << __func__ << ": cannot find string for section " << section
<< ", key " << key;
return false;
}
+ bool in_encrypt_key_name_list = btif_in_encrypt_key_name_list(key);
+ bool is_key_encrypted = *value_str_from_config == ENCRYPTED_STR;
+
+ if (!value_str_from_config->empty() && in_encrypt_key_name_list &&
+ is_key_encrypted) {
+ std::string string =
+ get_bluetooth_keystore_interface()->get_key(section + "-" + key);
+ value_str = &string;
+ } else {
+ value_str = value_str_from_config;
+ }
+
size_t value_len = value_str->length();
if ((value_len % 2) != 0 || *length < (value_len / 2)) {
LOG(WARNING) << ": value size not divisible by 2, size is " << value_len;
}
const char* ptr = value_str->c_str();
- for (*length = 0; *ptr; ptr += 2, *length += 1)
+ for (*length = 0; *ptr; ptr += 2, *length += 1) {
sscanf(ptr, "%02hhx", &value[*length]);
+ }
+
+ if (btif_is_niap_mode()) {
+ if (!value_str_from_config->empty() && in_encrypt_key_name_list &&
+ !is_key_encrypted) {
+ get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
+ section + "-" + key, *value_str_from_config);
+ config_set_string(config.get(), section, key, ENCRYPTED_STR);
+ }
+ } else {
+ if (in_encrypt_key_name_list && is_key_encrypted) {
+ config_set_string(config.get(), section, key, value_str->c_str());
+ }
+ }
return true;
}
str[(i * 2) + 1] = lookup[value[i] & 0x0F];
}
+ std::string value_str;
+ if ((length > 0) && btif_is_niap_mode() &&
+ btif_in_encrypt_key_name_list(key)) {
+ get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
+ section + "-" + key, str);
+ value_str = ENCRYPTED_STR;
+ } else {
+ value_str = str;
+ }
+
{
std::unique_lock<std::recursive_mutex> lock(config_lock);
storage_config_get_interface()->config_set_string(config.get(), section,
- key, str);
+ key, value_str);
}
osi_free(str);
bool btif_config_remove(const std::string& section, const std::string& key) {
CHECK(config != NULL);
+ if (is_niap_mode() && btif_in_encrypt_key_name_list(key)) {
+ get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
+ section + "-" + key, "");
+ }
std::unique_lock<std::recursive_mutex> lock(config_lock);
return storage_config_get_interface()->config_remove_key(config.get(),
section, key);
storage_config_get_interface()->config_new_clone(*config);
btif_config_remove_unpaired(config_paired.get());
storage_config_get_interface()->config_save(*config_paired, CONFIG_FILE_PATH);
+ if (btif_is_niap_mode()) {
+ get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
+ CONFIG_FILE_PREFIX, CONFIG_FILE_HASH);
+ }
}
static void btif_config_remove_unpaired(config_t* conf) {