1 /* keys.c - Bluetooth key handling */
2
3 /*
4 * Copyright (c) 2015-2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <ble_os.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <atomic.h>
13 #include <misc/util.h>
14
15 #include <settings/settings.h>
16
17 #include <bluetooth/bluetooth.h>
18 #include <bluetooth/conn.h>
19 #include <bluetooth/hci.h>
20
21 #if defined(CONFIG_BT_SMP)
22 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_KEYS)
23 #define LOG_MODULE_NAME bt_keys
24 #include "common/log.h"
25
26 #include "common/rpa.h"
27 #include "gatt_internal.h"
28 #include "hci_core.h"
29 #include "smp.h"
30 #include "settings.h"
31 #include "keys.h"
32 #include "bt_errno.h"
33
34 static struct bt_keys key_pool[CONFIG_BT_MAX_PAIRED];
35
36 #define BT_KEYS_STORAGE_LEN_COMPAT (BT_KEYS_STORAGE_LEN - sizeof(uint32_t))
37
38 #if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
39 static bt_u32_t aging_counter_val;
40 static struct bt_keys *last_keys_updated;
41 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
42
bt_keys_get_addr(u8_t id,const bt_addr_le_t * addr)43 struct bt_keys *bt_keys_get_addr(u8_t id, const bt_addr_le_t *addr)
44 {
45 struct bt_keys *keys;
46 int i;
47 size_t first_free_slot = ARRAY_SIZE(key_pool);
48
49 BT_DBG("%s", bt_addr_le_str(addr));
50
51 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
52 keys = &key_pool[i];
53
54 if (keys->id == id && !bt_addr_le_cmp(&keys->addr, addr)) {
55 return keys;
56 }
57
58 if (first_free_slot == ARRAY_SIZE(key_pool) &&
59 !bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) {
60 first_free_slot = i;
61 }
62 }
63
64 #if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
65 if (first_free_slot == ARRAY_SIZE(key_pool)) {
66 struct bt_keys *oldest = &key_pool[0];
67 bt_addr_le_t oldest_addr;
68
69 for (i = 1; i < ARRAY_SIZE(key_pool); i++) {
70 struct bt_keys *current = &key_pool[i];
71
72 if (current->aging_counter < oldest->aging_counter) {
73 oldest = current;
74 }
75 }
76
77 /* Use a copy as bt_unpair will clear the oldest key. */
78 bt_addr_le_copy(&oldest_addr, &oldest->addr);
79 bt_unpair(oldest->id, &oldest_addr);
80 if (!bt_addr_le_cmp(&oldest->addr, BT_ADDR_LE_ANY)) {
81 first_free_slot = oldest - &key_pool[0];
82 }
83 }
84
85 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
86 if (first_free_slot < ARRAY_SIZE(key_pool)) {
87 keys = &key_pool[first_free_slot];
88 keys->id = id;
89 bt_addr_le_copy(&keys->addr, addr);
90 #if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
91 keys->aging_counter = ++aging_counter_val;
92 last_keys_updated = keys;
93 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
94 BT_DBG("created %p for %s", keys, bt_addr_le_str(addr));
95 return keys;
96 }
97
98 BT_DBG("unable to create keys for %s", bt_addr_le_str(addr));
99
100 return NULL;
101 }
102
bt_foreach_bond(u8_t id,void (* func)(const struct bt_bond_info * info,void * user_data),void * user_data)103 void bt_foreach_bond(u8_t id, void (*func)(const struct bt_bond_info *info,
104 void *user_data),
105 void *user_data)
106 {
107 int i;
108
109 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
110 struct bt_keys *keys = &key_pool[i];
111
112 if (keys->keys && keys->id == id) {
113 struct bt_bond_info info;
114
115 bt_addr_le_copy(&info.addr, &keys->addr);
116 func(&info, user_data);
117 }
118 }
119 }
120
bt_keys_foreach(int type,void (* func)(struct bt_keys * keys,void * data),void * data)121 void bt_keys_foreach(int type, void (*func)(struct bt_keys *keys, void *data),
122 void *data)
123 {
124 int i;
125
126 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
127 if ((key_pool[i].keys & type)) {
128 func(&key_pool[i], data);
129 }
130 }
131 }
132
bt_keys_find(int type,u8_t id,const bt_addr_le_t * addr)133 struct bt_keys *bt_keys_find(int type, u8_t id, const bt_addr_le_t *addr)
134 {
135 int i;
136
137 BT_DBG("type %d %s", type, bt_addr_le_str(addr));
138
139 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
140 if ((key_pool[i].keys & type) && key_pool[i].id == id &&
141 !bt_addr_le_cmp(&key_pool[i].addr, addr)) {
142 return &key_pool[i];
143 }
144 }
145
146 return NULL;
147 }
148
bt_keys_get_type(int type,u8_t id,const bt_addr_le_t * addr)149 struct bt_keys *bt_keys_get_type(int type, u8_t id, const bt_addr_le_t *addr)
150 {
151 struct bt_keys *keys;
152
153 BT_DBG("type %d %s", type, bt_addr_le_str(addr));
154
155 keys = bt_keys_find(type, id, addr);
156 if (keys) {
157 return keys;
158 }
159
160 keys = bt_keys_get_addr(id, addr);
161 if (!keys) {
162 return NULL;
163 }
164
165 bt_keys_add_type(keys, type);
166
167 return keys;
168 }
169
bt_keys_find_irk(u8_t id,const bt_addr_le_t * addr)170 struct bt_keys *bt_keys_find_irk(u8_t id, const bt_addr_le_t *addr)
171 {
172 int i;
173
174 BT_DBG("%s", bt_addr_le_str(addr));
175
176 if (!bt_addr_le_is_rpa(addr)) {
177 return NULL;
178 }
179
180 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
181 if (!(key_pool[i].keys & BT_KEYS_IRK)) {
182 continue;
183 }
184
185 if (key_pool[i].id == id &&
186 !bt_addr_cmp(&addr->a, &key_pool[i].irk.rpa)) {
187 BT_DBG("cached RPA %s for %s",
188 bt_addr_str(&key_pool[i].irk.rpa),
189 bt_addr_le_str(&key_pool[i].addr));
190 return &key_pool[i];
191 }
192 }
193
194 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
195 if (!(key_pool[i].keys & BT_KEYS_IRK)) {
196 continue;
197 }
198
199 if (key_pool[i].id != id) {
200 continue;
201 }
202
203 if (bt_rpa_irk_matches(key_pool[i].irk.val, &addr->a)) {
204 BT_DBG("RPA %s matches %s",
205 bt_addr_str(&key_pool[i].irk.rpa),
206 bt_addr_le_str(&key_pool[i].addr));
207
208 bt_addr_copy(&key_pool[i].irk.rpa, &addr->a);
209
210 return &key_pool[i];
211 }
212 }
213
214 BT_DBG("No IRK for %s", bt_addr_le_str(addr));
215
216 return NULL;
217 }
218
bt_keys_find_addr(u8_t id,const bt_addr_le_t * addr)219 struct bt_keys *bt_keys_find_addr(u8_t id, const bt_addr_le_t *addr)
220 {
221 int i;
222
223 BT_DBG("%s", bt_addr_le_str(addr));
224
225 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
226 if (key_pool[i].id == id &&
227 !bt_addr_le_cmp(&key_pool[i].addr, addr)) {
228 return &key_pool[i];
229 }
230 }
231
232 return NULL;
233 }
234
bt_keys_add_type(struct bt_keys * keys,int type)235 void bt_keys_add_type(struct bt_keys *keys, int type)
236 {
237 keys->keys |= type;
238 }
239
bt_keys_clear(struct bt_keys * keys)240 void bt_keys_clear(struct bt_keys *keys)
241 {
242 BT_DBG("%s (keys 0x%04x)", bt_addr_le_str(&keys->addr), keys->keys);
243
244 if (keys->state & BT_KEYS_ID_ADDED) {
245 bt_id_del(keys);
246 }
247
248 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
249 char key[BT_SETTINGS_KEY_MAX];
250
251 /* Delete stored keys from flash */
252 if (keys->id) {
253 char id[4];
254
255 u8_to_dec(id, sizeof(id), keys->id);
256 bt_settings_encode_key(key, sizeof(key), "keys",
257 &keys->addr, id);
258 } else {
259 bt_settings_encode_key(key, sizeof(key), "keys",
260 &keys->addr, NULL);
261 }
262
263 BT_DBG("Deleting key %s", log_strdup(key));
264 settings_delete(key);
265 }
266
267 (void)memset(keys, 0, sizeof(*keys));
268 }
269
270 #if defined(CONFIG_BT_SETTINGS)
bt_keys_store(struct bt_keys * keys)271 int bt_keys_store(struct bt_keys *keys)
272 {
273 char key[BT_SETTINGS_KEY_MAX];
274 int err;
275
276 if (keys->id) {
277 char id[4];
278
279 u8_to_dec(id, sizeof(id), keys->id);
280 bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr,
281 id);
282 } else {
283 bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr,
284 NULL);
285 }
286
287 err = settings_save_one(key, keys->storage_start, BT_KEYS_STORAGE_LEN);
288 if (err) {
289 BT_ERR("Failed to save keys (err %d)", err);
290 return err;
291 }
292
293 BT_DBG("Stored keys for %s (%s)", bt_addr_le_str(&keys->addr),
294 log_strdup(key));
295
296 return 0;
297 }
298
keys_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)299 static int keys_set(const char *name, size_t len_rd, settings_read_cb read_cb,
300 void *cb_arg)
301 {
302 struct bt_keys *keys;
303 bt_addr_le_t addr;
304 u8_t id;
305 ssize_t len;
306 int err;
307 char val[BT_KEYS_STORAGE_LEN];
308 const char *next;
309
310 if (!name) {
311 BT_ERR("Insufficient number of arguments");
312 return -EINVAL;
313 }
314
315 len = read_cb(cb_arg, val, sizeof(val));
316 if (len < 0) {
317 BT_ERR("Failed to read value (err %zd)", len);
318 return -EINVAL;
319 }
320
321 BT_DBG("name %s val %s", log_strdup(name),
322 (len) ? bt_hex(val, sizeof(val)) : "(null)");
323
324 err = bt_settings_decode_key(name, &addr);
325 if (err) {
326 BT_ERR("Unable to decode address %s", name);
327 return -EINVAL;
328 }
329
330 settings_name_next(name, &next);
331
332 if (!next) {
333 id = BT_ID_DEFAULT;
334 } else {
335 id = strtol(next, NULL, 10);
336 }
337
338 if (!len) {
339 keys = bt_keys_find(BT_KEYS_ALL, id, &addr);
340 if (keys) {
341 (void)memset(keys, 0, sizeof(*keys));
342 BT_DBG("Cleared keys for %s", bt_addr_le_str(&addr));
343 } else {
344 BT_WARN("Unable to find deleted keys for %s",
345 bt_addr_le_str(&addr));
346 }
347
348 return 0;
349 }
350
351 keys = bt_keys_get_addr(id, &addr);
352 if (!keys) {
353 BT_ERR("Failed to allocate keys for %s", bt_addr_le_str(&addr));
354 return -ENOMEM;
355 }
356 if (len != BT_KEYS_STORAGE_LEN) {
357 do {
358 /* Load shorter structure for compatibility with old
359 * records format with no counter.
360 */
361 if (IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) &&
362 len == BT_KEYS_STORAGE_LEN_COMPAT) {
363 BT_WARN("Keys for %s have no aging counter",
364 bt_addr_le_str(&addr));
365 memcpy(keys->storage_start, val, len);
366 continue;
367 }
368
369 BT_ERR("Invalid key length %zd != %zu", len,
370 BT_KEYS_STORAGE_LEN);
371 bt_keys_clear(keys);
372
373 return -EINVAL;
374 } while (0);
375 } else {
376 memcpy(keys->storage_start, val, len);
377 }
378
379 BT_DBG("Successfully restored keys for %s", bt_addr_le_str(&addr));
380 #if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
381 if (aging_counter_val < keys->aging_counter) {
382 aging_counter_val = keys->aging_counter;
383 }
384 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
385 return 0;
386 }
387
id_add(struct bt_keys * keys,void * user_data)388 static void id_add(struct bt_keys *keys, void *user_data)
389 {
390 bt_id_add(keys);
391 }
392
keys_commit(void)393 static int keys_commit(void)
394 {
395 BT_DBG("");
396
397 /* We do this in commit() rather than add() since add() may get
398 * called multiple times for the same address, especially if
399 * the keys were already removed.
400 */
401 if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PRIVACY)) {
402 bt_keys_foreach(BT_KEYS_ALL, id_add, NULL);
403 } else {
404 bt_keys_foreach(BT_KEYS_IRK, id_add, NULL);
405 }
406
407 return 0;
408 }
409
410 //SETTINGS_STATIC_HANDLER_DEFINE(bt_keys, "bt/keys", NULL, keys_set, keys_commit,
411 // NULL);
412
bt_key_settings_init()413 int bt_key_settings_init()
414 {
415 SETTINGS_HANDLER_DEFINE(bt_keys, "bt/keys", NULL, keys_set, keys_commit,
416 NULL);
417 return 0;
418 }
419
420 #endif /* CONFIG_BT_SETTINGS */
421
422 #if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
bt_keys_update_usage(u8_t id,const bt_addr_le_t * addr)423 void bt_keys_update_usage(u8_t id, const bt_addr_le_t *addr)
424 {
425 struct bt_keys *keys = bt_keys_find_addr(id, addr);
426
427 if (!keys) {
428 return;
429 }
430
431 if (last_keys_updated == keys) {
432 return;
433 }
434
435 keys->aging_counter = ++aging_counter_val;
436 last_keys_updated = keys;
437
438 BT_DBG("Aging counter for %s is set to %u", bt_addr_le_str(addr),
439 keys->aging_counter);
440
441 if (IS_ENABLED(CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING)) {
442 bt_keys_store(keys);
443 }
444 }
445
446 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
447 #endif
448