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 <zephyr/kernel.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <zephyr/sys/atomic.h>
13 #include <zephyr/sys/util.h>
14 #include <zephyr/sys/byteorder.h>
15
16 #include <zephyr/settings/settings.h>
17
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/bluetooth/buf.h>
20 #include <zephyr/bluetooth/conn.h>
21 #include <zephyr/bluetooth/hci.h>
22
23 #include "common/bt_str.h"
24
25 #include "common/rpa.h"
26 #include "conn_internal.h"
27 #include "gatt_internal.h"
28 #include "hci_core.h"
29 #include "smp.h"
30 #include "settings.h"
31 #include "keys.h"
32
33 #define LOG_LEVEL CONFIG_BT_KEYS_LOG_LEVEL
34 #include <zephyr/logging/log.h>
35 LOG_MODULE_REGISTER(bt_keys);
36
37 static struct bt_keys key_pool[CONFIG_BT_MAX_PAIRED];
38
39 #define BT_KEYS_STORAGE_LEN_COMPAT (BT_KEYS_STORAGE_LEN - sizeof(uint32_t))
40
41 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
42 static uint32_t aging_counter_val;
43 static struct bt_keys *last_keys_updated;
44
45 struct key_data {
46 bool in_use;
47 uint8_t id;
48 };
49
find_key_in_use(struct bt_conn * conn,void * data)50 static void find_key_in_use(struct bt_conn *conn, void *data)
51 {
52 struct key_data *kdata = data;
53 struct bt_keys *key;
54
55 __ASSERT_NO_MSG(conn != NULL);
56 __ASSERT_NO_MSG(data != NULL);
57
58 if (conn->state == BT_CONN_CONNECTED) {
59 key = bt_keys_find_addr(conn->id, bt_conn_get_dst(conn));
60 if (key == NULL) {
61 return;
62 }
63
64 /* Ensure that the reference returned matches the current pool item */
65 if (key == &key_pool[kdata->id]) {
66 kdata->in_use = true;
67 LOG_DBG("Connected device %s is using key_pool[%d]",
68 bt_addr_le_str(bt_conn_get_dst(conn)), kdata->id);
69 }
70 }
71 }
72
key_is_in_use(uint8_t id)73 static bool key_is_in_use(uint8_t id)
74 {
75 struct key_data kdata = { false, id };
76
77 bt_conn_foreach(BT_CONN_TYPE_ALL, find_key_in_use, &kdata);
78
79 return kdata.in_use;
80 }
81 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
82
bt_keys_reset(void)83 void bt_keys_reset(void)
84 {
85 memset(key_pool, 0, sizeof(key_pool));
86 }
87
bt_keys_get_addr(uint8_t id,const bt_addr_le_t * addr)88 struct bt_keys *bt_keys_get_addr(uint8_t id, const bt_addr_le_t *addr)
89 {
90 struct bt_keys *keys;
91 int i;
92 size_t first_free_slot = ARRAY_SIZE(key_pool);
93
94 __ASSERT_NO_MSG(addr != NULL);
95
96 LOG_DBG("%s", bt_addr_le_str(addr));
97
98 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
99 keys = &key_pool[i];
100
101 if (keys->id == id && bt_addr_le_eq(&keys->addr, addr)) {
102 return keys;
103 }
104 if (first_free_slot == ARRAY_SIZE(key_pool) &&
105 bt_addr_le_eq(&keys->addr, BT_ADDR_LE_ANY)) {
106 first_free_slot = i;
107 }
108 }
109
110 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
111 if (first_free_slot == ARRAY_SIZE(key_pool)) {
112 struct bt_keys *oldest = NULL;
113 bt_addr_le_t oldest_addr;
114
115 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
116 struct bt_keys *current = &key_pool[i];
117 bool key_in_use = key_is_in_use(i);
118
119 if (key_in_use) {
120 continue;
121 }
122
123 if ((oldest == NULL) || (current->aging_counter < oldest->aging_counter)) {
124 oldest = current;
125 }
126 }
127
128 if (oldest == NULL) {
129 LOG_DBG("unable to create keys for %s", bt_addr_le_str(addr));
130 return NULL;
131 }
132
133 /* Use a copy as bt_unpair will clear the oldest key. */
134 bt_addr_le_copy(&oldest_addr, &oldest->addr);
135 bt_unpair(oldest->id, &oldest_addr);
136 if (bt_addr_le_eq(&oldest->addr, BT_ADDR_LE_ANY)) {
137 first_free_slot = oldest - &key_pool[0];
138 }
139 }
140
141 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
142 if (first_free_slot < ARRAY_SIZE(key_pool)) {
143 keys = &key_pool[first_free_slot];
144 keys->id = id;
145 bt_addr_le_copy(&keys->addr, addr);
146 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
147 keys->aging_counter = ++aging_counter_val;
148 last_keys_updated = keys;
149 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
150 LOG_DBG("created %p for %s", keys, bt_addr_le_str(addr));
151 return keys;
152 }
153
154 LOG_DBG("unable to create keys for %s", bt_addr_le_str(addr));
155
156 return NULL;
157 }
158
bt_foreach_bond(uint8_t id,void (* func)(const struct bt_bond_info * info,void * user_data),void * user_data)159 void bt_foreach_bond(uint8_t id, void (*func)(const struct bt_bond_info *info,
160 void *user_data),
161 void *user_data)
162 {
163 int i;
164
165 __ASSERT_NO_MSG(func != NULL);
166
167 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
168 struct bt_keys *keys = &key_pool[i];
169
170 if (keys->keys && keys->id == id) {
171 struct bt_bond_info info;
172
173 bt_addr_le_copy(&info.addr, &keys->addr);
174 func(&info, user_data);
175 }
176 }
177
178 if (IS_ENABLED(CONFIG_BT_CLASSIC)) {
179 bt_foreach_bond_br(func, user_data);
180 }
181 }
182
bt_keys_foreach_type(enum bt_keys_type type,void (* func)(struct bt_keys * keys,void * data),void * data)183 void bt_keys_foreach_type(enum bt_keys_type type, void (*func)(struct bt_keys *keys, void *data),
184 void *data)
185 {
186 int i;
187
188 __ASSERT_NO_MSG(func != NULL);
189
190 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
191 if ((key_pool[i].keys & type)) {
192 func(&key_pool[i], data);
193 }
194 }
195 }
196
bt_keys_find(enum bt_keys_type type,uint8_t id,const bt_addr_le_t * addr)197 struct bt_keys *bt_keys_find(enum bt_keys_type type, uint8_t id, const bt_addr_le_t *addr)
198 {
199 int i;
200
201 __ASSERT_NO_MSG(addr != NULL);
202
203 LOG_DBG("type %d %s", type, bt_addr_le_str(addr));
204
205 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
206 if ((key_pool[i].keys & type) && key_pool[i].id == id &&
207 bt_addr_le_eq(&key_pool[i].addr, addr)) {
208 return &key_pool[i];
209 }
210 }
211
212 return NULL;
213 }
214
bt_keys_get_type(enum bt_keys_type type,uint8_t id,const bt_addr_le_t * addr)215 struct bt_keys *bt_keys_get_type(enum bt_keys_type type, uint8_t id, const bt_addr_le_t *addr)
216 {
217 struct bt_keys *keys;
218
219 __ASSERT_NO_MSG(addr != NULL);
220
221 LOG_DBG("type %d %s", type, bt_addr_le_str(addr));
222
223 keys = bt_keys_find(type, id, addr);
224 if (keys) {
225 return keys;
226 }
227
228 keys = bt_keys_get_addr(id, addr);
229 if (!keys) {
230 return NULL;
231 }
232
233 bt_keys_add_type(keys, type);
234
235 return keys;
236 }
237
bt_keys_find_irk(uint8_t id,const bt_addr_le_t * addr)238 struct bt_keys *bt_keys_find_irk(uint8_t id, const bt_addr_le_t *addr)
239 {
240 int i;
241
242 __ASSERT_NO_MSG(addr != NULL);
243
244 LOG_DBG("%s", bt_addr_le_str(addr));
245
246 if (!bt_addr_le_is_rpa(addr)) {
247 return NULL;
248 }
249
250 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
251 if (!(key_pool[i].keys & BT_KEYS_IRK)) {
252 continue;
253 }
254
255 if (key_pool[i].id == id &&
256 bt_addr_eq(&addr->a, &key_pool[i].irk.rpa)) {
257 LOG_DBG("cached RPA %s for %s", bt_addr_str(&key_pool[i].irk.rpa),
258 bt_addr_le_str(&key_pool[i].addr));
259 return &key_pool[i];
260 }
261 }
262
263 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
264 if (!(key_pool[i].keys & BT_KEYS_IRK)) {
265 continue;
266 }
267
268 if (key_pool[i].id != id) {
269 continue;
270 }
271
272 if (bt_rpa_irk_matches(key_pool[i].irk.val, &addr->a)) {
273 LOG_DBG("RPA %s matches %s", bt_addr_str(&key_pool[i].irk.rpa),
274 bt_addr_le_str(&key_pool[i].addr));
275
276 bt_addr_copy(&key_pool[i].irk.rpa, &addr->a);
277
278 return &key_pool[i];
279 }
280 }
281
282 LOG_DBG("No IRK for %s", bt_addr_le_str(addr));
283
284 return NULL;
285 }
286
bt_keys_find_addr(uint8_t id,const bt_addr_le_t * addr)287 struct bt_keys *bt_keys_find_addr(uint8_t id, const bt_addr_le_t *addr)
288 {
289 int i;
290
291 __ASSERT_NO_MSG(addr != NULL);
292
293 LOG_DBG("%s", bt_addr_le_str(addr));
294
295 for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
296 if (key_pool[i].id == id &&
297 bt_addr_le_eq(&key_pool[i].addr, addr)) {
298 return &key_pool[i];
299 }
300 }
301
302 return NULL;
303 }
304
bt_keys_add_type(struct bt_keys * keys,enum bt_keys_type type)305 void bt_keys_add_type(struct bt_keys *keys, enum bt_keys_type type)
306 {
307 __ASSERT_NO_MSG(keys != NULL);
308
309 keys->keys |= type;
310 }
311
bt_keys_clear(struct bt_keys * keys)312 void bt_keys_clear(struct bt_keys *keys)
313 {
314 __ASSERT_NO_MSG(keys != NULL);
315
316 LOG_DBG("%s (keys 0x%04x)", bt_addr_le_str(&keys->addr), keys->keys);
317
318 if (keys->state & BT_KEYS_ID_ADDED) {
319 bt_id_del(keys);
320 }
321
322 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
323 /* Delete stored keys from flash */
324 bt_settings_delete_keys(keys->id, &keys->addr);
325 }
326
327 (void)memset(keys, 0, sizeof(*keys));
328 }
329
330 #if defined(CONFIG_BT_SETTINGS)
bt_keys_store(struct bt_keys * keys)331 int bt_keys_store(struct bt_keys *keys)
332 {
333 int err;
334
335 __ASSERT_NO_MSG(keys != NULL);
336
337 err = bt_settings_store_keys(keys->id, &keys->addr, keys->storage_start,
338 BT_KEYS_STORAGE_LEN);
339 if (err) {
340 LOG_ERR("Failed to save keys (err %d)", err);
341 return err;
342 }
343
344 LOG_DBG("Stored keys for %s", bt_addr_le_str(&keys->addr));
345
346 return 0;
347 }
348
keys_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)349 static int keys_set(const char *name, size_t len_rd, settings_read_cb read_cb,
350 void *cb_arg)
351 {
352 struct bt_keys *keys;
353 bt_addr_le_t addr;
354 uint8_t id;
355 ssize_t len;
356 int err;
357 char val[BT_KEYS_STORAGE_LEN];
358 const char *next;
359
360 if (!name) {
361 LOG_ERR("Insufficient number of arguments");
362 return -EINVAL;
363 }
364
365 len = read_cb(cb_arg, val, sizeof(val));
366 if (len < 0) {
367 LOG_ERR("Failed to read value (err %zd)", len);
368 return -EINVAL;
369 }
370
371 LOG_DBG("name %s val %s", name, (len) ? bt_hex(val, sizeof(val)) : "(null)");
372
373 err = bt_settings_decode_key(name, &addr);
374 if (err) {
375 LOG_ERR("Unable to decode address %s", name);
376 return -EINVAL;
377 }
378
379 settings_name_next(name, &next);
380
381 if (!next) {
382 id = BT_ID_DEFAULT;
383 } else {
384 unsigned long next_id = strtoul(next, NULL, 10);
385
386 if (next_id >= CONFIG_BT_ID_MAX) {
387 LOG_ERR("Invalid local identity %lu", next_id);
388 return -EINVAL;
389 }
390
391 id = (uint8_t)next_id;
392 }
393
394 if (!len) {
395 keys = bt_keys_find(BT_KEYS_ALL, id, &addr);
396 if (keys) {
397 (void)memset(keys, 0, sizeof(*keys));
398 LOG_DBG("Cleared keys for %s", bt_addr_le_str(&addr));
399 } else {
400 LOG_WRN("Unable to find deleted keys for %s", bt_addr_le_str(&addr));
401 }
402
403 return 0;
404 }
405
406 keys = bt_keys_get_addr(id, &addr);
407 if (!keys) {
408 LOG_ERR("Failed to allocate keys for %s", bt_addr_le_str(&addr));
409 return -ENOMEM;
410 }
411 if (len != BT_KEYS_STORAGE_LEN) {
412 if (IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) &&
413 len == BT_KEYS_STORAGE_LEN_COMPAT) {
414 /* Load shorter structure for compatibility with old
415 * records format with no counter.
416 */
417 LOG_WRN("Keys for %s have no aging counter", bt_addr_le_str(&addr));
418 memcpy(keys->storage_start, val, len);
419 } else {
420 LOG_ERR("Invalid key length %zd != %zu", len, BT_KEYS_STORAGE_LEN);
421 bt_keys_clear(keys);
422
423 return -EINVAL;
424 }
425 } else {
426 memcpy(keys->storage_start, val, len);
427 }
428
429 LOG_DBG("Successfully restored keys for %s", bt_addr_le_str(&addr));
430 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
431 if (aging_counter_val < keys->aging_counter) {
432 aging_counter_val = keys->aging_counter;
433 }
434 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
435 return 0;
436 }
437
id_add(struct bt_keys * keys,void * user_data)438 static void id_add(struct bt_keys *keys, void *user_data)
439 {
440 __ASSERT_NO_MSG(keys != NULL);
441
442 bt_id_add(keys);
443 }
444
keys_commit(void)445 static int keys_commit(void)
446 {
447 /* We do this in commit() rather than add() since add() may get
448 * called multiple times for the same address, especially if
449 * the keys were already removed.
450 */
451 if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PRIVACY)) {
452 bt_keys_foreach_type(BT_KEYS_ALL, id_add, NULL);
453 } else {
454 bt_keys_foreach_type(BT_KEYS_IRK, id_add, NULL);
455 }
456
457 return 0;
458 }
459
460 BT_SETTINGS_DEFINE(keys, "keys", keys_set, keys_commit);
461
462 #endif /* CONFIG_BT_SETTINGS */
463
464 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
bt_keys_update_usage(uint8_t id,const bt_addr_le_t * addr)465 void bt_keys_update_usage(uint8_t id, const bt_addr_le_t *addr)
466 {
467 __ASSERT_NO_MSG(addr != NULL);
468
469 struct bt_keys *keys = bt_keys_find_addr(id, addr);
470
471 if (!keys) {
472 return;
473 }
474
475 if (last_keys_updated == keys) {
476 return;
477 }
478
479 keys->aging_counter = ++aging_counter_val;
480 last_keys_updated = keys;
481
482 LOG_DBG("Aging counter for %s is set to %u", bt_addr_le_str(addr), keys->aging_counter);
483
484 if (IS_ENABLED(CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING)) {
485 bt_keys_store(keys);
486 }
487 }
488
489 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
490
491 #if defined(CONFIG_BT_LOG_SNIFFER_INFO)
bt_keys_show_sniffer_info(struct bt_keys * keys,void * data)492 void bt_keys_show_sniffer_info(struct bt_keys *keys, void *data)
493 {
494 uint8_t ltk[16];
495
496 __ASSERT_NO_MSG(keys != NULL);
497
498 if (keys->keys & BT_KEYS_LTK_P256) {
499 sys_memcpy_swap(ltk, keys->ltk.val, keys->enc_size);
500 LOG_INF("SC LTK: 0x%s", bt_hex(ltk, keys->enc_size));
501 }
502
503 #if !defined(CONFIG_BT_SMP_SC_PAIR_ONLY)
504 if (keys->keys & BT_KEYS_PERIPH_LTK) {
505 sys_memcpy_swap(ltk, keys->periph_ltk.val, keys->enc_size);
506 LOG_INF("Legacy LTK: 0x%s (peripheral)", bt_hex(ltk, keys->enc_size));
507 }
508 #endif /* !CONFIG_BT_SMP_SC_PAIR_ONLY */
509
510 if (keys->keys & BT_KEYS_LTK) {
511 sys_memcpy_swap(ltk, keys->ltk.val, keys->enc_size);
512 LOG_INF("Legacy LTK: 0x%s (central)", bt_hex(ltk, keys->enc_size));
513 }
514 }
515 #endif /* defined(CONFIG_BT_LOG_SNIFFER_INFO) */
516
517 #ifdef ZTEST_UNITTEST
bt_keys_get_key_pool(void)518 struct bt_keys *bt_keys_get_key_pool(void)
519 {
520 return key_pool;
521 }
522
523 #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
bt_keys_get_aging_counter_val(void)524 uint32_t bt_keys_get_aging_counter_val(void)
525 {
526 return aging_counter_val;
527 }
528
bt_keys_get_last_keys_updated(void)529 struct bt_keys *bt_keys_get_last_keys_updated(void)
530 {
531 return last_keys_updated;
532 }
533 #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
534 #endif /* ZTEST_UNITTEST */
535