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 "host/hci_core.h"
22 #include "host/settings.h"
23 #include "host/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 
bt_foreach_bond_br(void (* func)(const struct bt_bond_info * info,void * user_data),void * user_data)149 void bt_foreach_bond_br(void (*func)(const struct bt_bond_info *info, void *user_data),
150 			void *user_data)
151 {
152 	__ASSERT_NO_MSG(func != NULL);
153 
154 	for (size_t i = 0; i < ARRAY_SIZE(key_pool); i++) {
155 		const struct bt_keys_link_key *key = &key_pool[i];
156 
157 		if (!bt_addr_eq(&key->addr, BT_ADDR_ANY)) {
158 			struct bt_bond_info info;
159 
160 			info.addr.type = BT_ADDR_LE_PUBLIC;
161 			bt_addr_copy(&info.addr.a, &key->addr);
162 			func(&info, user_data);
163 		}
164 	}
165 }
166 
167 #if defined(CONFIG_BT_SETTINGS)
168 
link_key_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)169 static int link_key_set(const char *name, size_t len_rd,
170 			settings_read_cb read_cb, void *cb_arg)
171 {
172 	int err;
173 	ssize_t len;
174 	bt_addr_le_t le_addr;
175 	struct bt_keys_link_key *link_key;
176 	char val[BT_KEYS_LINK_KEY_STORAGE_LEN];
177 
178 	if (!name) {
179 		LOG_ERR("Insufficient number of arguments");
180 		return -EINVAL;
181 	}
182 
183 	len = read_cb(cb_arg, val, sizeof(val));
184 	if (len < 0) {
185 		LOG_ERR("Failed to read value (err %zu)", len);
186 		return -EINVAL;
187 	}
188 
189 	LOG_DBG("name %s val %s", name, len ? bt_hex(val, sizeof(val)) : "(null)");
190 
191 	err = bt_settings_decode_key(name, &le_addr);
192 	if (err) {
193 		LOG_ERR("Unable to decode address %s", name);
194 		return -EINVAL;
195 	}
196 
197 	link_key = bt_keys_get_link_key(&le_addr.a);
198 	if (len != BT_KEYS_LINK_KEY_STORAGE_LEN) {
199 		if (link_key) {
200 			bt_keys_link_key_clear(link_key);
201 			LOG_DBG("Clear keys for %s", bt_addr_le_str(&le_addr));
202 		} else {
203 			LOG_WRN("Unable to find deleted keys for %s", bt_addr_le_str(&le_addr));
204 		}
205 
206 		return 0;
207 	}
208 
209 	memcpy(link_key->storage_start, val, len);
210 	LOG_DBG("Successfully restored link key for %s", bt_addr_le_str(&le_addr));
211 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
212 	if (aging_counter_val < link_key->aging_counter) {
213 		aging_counter_val = link_key->aging_counter;
214 	}
215 #endif  /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
216 
217 	return 0;
218 }
219 
220 SETTINGS_STATIC_HANDLER_DEFINE(bt_link_key, "bt/link_key", NULL, link_key_set,
221 			       NULL, NULL);
222 
223 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
bt_keys_link_key_update_usage(const bt_addr_t * addr)224 void bt_keys_link_key_update_usage(const bt_addr_t *addr)
225 {
226 	struct bt_keys_link_key *link_key = bt_keys_find_link_key(addr);
227 
228 	if (!link_key) {
229 		return;
230 	}
231 
232 	if (last_keys_updated == link_key) {
233 		return;
234 	}
235 
236 	link_key->aging_counter = ++aging_counter_val;
237 	last_keys_updated = link_key;
238 
239 	LOG_DBG("Aging counter for %s is set to %u", bt_addr_str(addr), link_key->aging_counter);
240 
241 	if (IS_ENABLED(CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING)) {
242 		bt_keys_link_key_store(link_key);
243 	}
244 }
245 #endif  /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
246 
247 #endif /* defined(CONFIG_BT_SETTINGS) */
248