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