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