1 /* keys_br.c - Bluetooth BR/EDR key handling */
2 
3 /*
4  * Copyright (c) 2015-2016 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/kernel.h>
10 #include <string.h>
11 #include <zephyr/sys/atomic.h>
12 #include <zephyr/sys/util.h>
13 
14 #include <zephyr/bluetooth/bluetooth.h>
15 #include <zephyr/bluetooth/conn.h>
16 #include <zephyr/bluetooth/hci.h>
17 #include <zephyr/settings/settings.h>
18 
19 #include "common/bt_str.h"
20 
21 #include "hci_core.h"
22 #include "settings.h"
23 #include "keys.h"
24 
25 #define LOG_LEVEL CONFIG_BT_KEYS_LOG_LEVEL
26 #include <zephyr/logging/log.h>
27 LOG_MODULE_REGISTER(bt_keys_br);
28 
29 static struct bt_keys_link_key key_pool[CONFIG_BT_MAX_PAIRED];
30 
31 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
32 static uint32_t aging_counter_val;
33 static struct bt_keys_link_key *last_keys_updated;
34 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
35 
bt_keys_find_link_key(const bt_addr_t * addr)36 struct bt_keys_link_key *bt_keys_find_link_key(const bt_addr_t *addr)
37 {
38 	struct bt_keys_link_key *key;
39 	int i;
40 
41 	LOG_DBG("%s", bt_addr_str(addr));
42 
43 	for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
44 		key = &key_pool[i];
45 
46 		if (bt_addr_eq(&key->addr, addr)) {
47 			return key;
48 		}
49 	}
50 
51 	return NULL;
52 }
53 
bt_keys_get_link_key(const bt_addr_t * addr)54 struct bt_keys_link_key *bt_keys_get_link_key(const bt_addr_t *addr)
55 {
56 	struct bt_keys_link_key *key;
57 
58 	key = bt_keys_find_link_key(addr);
59 	if (key) {
60 		return key;
61 	}
62 
63 	key = bt_keys_find_link_key(BT_ADDR_ANY);
64 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
65 	if (!key) {
66 		int i;
67 
68 		key = &key_pool[0];
69 		for (i = 1; i < ARRAY_SIZE(key_pool); i++) {
70 			struct bt_keys_link_key *current = &key_pool[i];
71 
72 			if (current->aging_counter < key->aging_counter) {
73 				key = current;
74 			}
75 		}
76 
77 		if (key) {
78 			bt_keys_link_key_clear(key);
79 		}
80 	}
81 #endif
82 
83 	if (key) {
84 		bt_addr_copy(&key->addr, addr);
85 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
86 		key->aging_counter = ++aging_counter_val;
87 		last_keys_updated = key;
88 #endif
89 		LOG_DBG("created %p for %s", key, bt_addr_str(addr));
90 		return key;
91 	}
92 
93 	LOG_DBG("unable to create keys for %s", bt_addr_str(addr));
94 
95 	return NULL;
96 }
97 
bt_keys_link_key_clear(struct bt_keys_link_key * link_key)98 void bt_keys_link_key_clear(struct bt_keys_link_key *link_key)
99 {
100 	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
101 		bt_addr_le_t le_addr;
102 
103 		le_addr.type = BT_ADDR_LE_PUBLIC;
104 		bt_addr_copy(&le_addr.a, &link_key->addr);
105 
106 		bt_settings_delete_link_key(&le_addr);
107 	}
108 
109 	LOG_DBG("%s", bt_addr_str(&link_key->addr));
110 	(void)memset(link_key, 0, sizeof(*link_key));
111 }
112 
bt_keys_link_key_clear_addr(const bt_addr_t * addr)113 void bt_keys_link_key_clear_addr(const bt_addr_t *addr)
114 {
115 	int i;
116 	struct bt_keys_link_key *key;
117 
118 	if (!addr) {
119 		for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
120 			key = &key_pool[i];
121 			bt_keys_link_key_clear(key);
122 		}
123 		return;
124 	}
125 
126 	key = bt_keys_find_link_key(addr);
127 	if (key) {
128 		bt_keys_link_key_clear(key);
129 	}
130 }
131 
bt_keys_link_key_store(struct bt_keys_link_key * link_key)132 void bt_keys_link_key_store(struct bt_keys_link_key *link_key)
133 {
134 	if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
135 		int err;
136 		bt_addr_le_t le_addr;
137 
138 		le_addr.type = BT_ADDR_LE_PUBLIC;
139 		bt_addr_copy(&le_addr.a, &link_key->addr);
140 
141 		err = bt_settings_store_link_key(&le_addr, link_key->storage_start,
142 						 BT_KEYS_LINK_KEY_STORAGE_LEN);
143 		if (err) {
144 			LOG_ERR("Failed to save link key (err %d)", err);
145 		}
146 	}
147 }
148 
149 #if defined(CONFIG_BT_SETTINGS)
150 
link_key_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)151 static int link_key_set(const char *name, size_t len_rd,
152 			settings_read_cb read_cb, void *cb_arg)
153 {
154 	int err;
155 	ssize_t len;
156 	bt_addr_le_t le_addr;
157 	struct bt_keys_link_key *link_key;
158 	char val[BT_KEYS_LINK_KEY_STORAGE_LEN];
159 
160 	if (!name) {
161 		LOG_ERR("Insufficient number of arguments");
162 		return -EINVAL;
163 	}
164 
165 	len = read_cb(cb_arg, val, sizeof(val));
166 	if (len < 0) {
167 		LOG_ERR("Failed to read value (err %zu)", len);
168 		return -EINVAL;
169 	}
170 
171 	LOG_DBG("name %s val %s", name, len ? bt_hex(val, sizeof(val)) : "(null)");
172 
173 	err = bt_settings_decode_key(name, &le_addr);
174 	if (err) {
175 		LOG_ERR("Unable to decode address %s", name);
176 		return -EINVAL;
177 	}
178 
179 	link_key = bt_keys_get_link_key(&le_addr.a);
180 	if (len != BT_KEYS_LINK_KEY_STORAGE_LEN) {
181 		if (link_key) {
182 			bt_keys_link_key_clear(link_key);
183 			LOG_DBG("Clear keys for %s", bt_addr_le_str(&le_addr));
184 		} else {
185 			LOG_WRN("Unable to find deleted keys for %s", bt_addr_le_str(&le_addr));
186 		}
187 
188 		return 0;
189 	}
190 
191 	memcpy(link_key->storage_start, val, len);
192 	LOG_DBG("Successfully restored link key for %s", bt_addr_le_str(&le_addr));
193 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
194 	if (aging_counter_val < link_key->aging_counter) {
195 		aging_counter_val = link_key->aging_counter;
196 	}
197 #endif  /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
198 
199 	return 0;
200 }
201 
202 SETTINGS_STATIC_HANDLER_DEFINE(bt_link_key, "bt/link_key", NULL, link_key_set,
203 			       NULL, NULL);
204 
205 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
bt_keys_link_key_update_usage(const bt_addr_t * addr)206 void bt_keys_link_key_update_usage(const bt_addr_t *addr)
207 {
208 	struct bt_keys_link_key *link_key = bt_keys_find_link_key(addr);
209 
210 	if (!link_key) {
211 		return;
212 	}
213 
214 	if (last_keys_updated == link_key) {
215 		return;
216 	}
217 
218 	link_key->aging_counter = ++aging_counter_val;
219 	last_keys_updated = link_key;
220 
221 	LOG_DBG("Aging counter for %s is set to %u", bt_addr_str(addr), link_key->aging_counter);
222 
223 	if (IS_ENABLED(CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING)) {
224 		bt_keys_link_key_store(link_key);
225 	}
226 }
227 #endif  /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
228 
229 #endif /* defined(CONFIG_BT_SETTINGS) */
230