1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains functions for the Bluetooth Device Manager
22 *
23 ******************************************************************************/
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <stddef.h>
29
30 #include "bt_types.h"
31 #include "device/include/controller.h"
32 #include "bt_common.h"
33 #include "hcimsgs.h"
34 #include "btu.h"
35 #include "btm_api.h"
36 #include "btm_int.h"
37 #include "hcidefs.h"
38 #include "l2c_api.h"
39
40 static tBTM_SEC_DEV_REC *btm_find_oldest_dev (void);
41
42 /*******************************************************************************
43 **
44 ** Function BTM_SecAddDevice
45 **
46 ** Description Add/modify device. This function will be normally called
47 ** during host startup to restore all required information
48 ** stored in the NVRAM.
49 **
50 ** Parameters: bd_addr - BD address of the peer
51 ** dev_class - Device Class
52 ** bd_name - Name of the peer device. NULL if unknown.
53 ** features - Remote device's features (up to 3 pages). NULL if not known
54 ** trusted_mask - Bitwise OR of services that do not
55 ** require authorization. (array of UINT32)
56 ** link_key - Connection link key. NULL if unknown.
57 **
58 ** Returns TRUE if added OK, else FALSE
59 **
60 *******************************************************************************/
BTM_SecAddDevice(BD_ADDR bd_addr,DEV_CLASS dev_class,BD_NAME bd_name,UINT8 * features,UINT32 trusted_mask[],LINK_KEY link_key,UINT8 key_type,tBTM_IO_CAP io_cap,UINT8 pin_length)61 BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
62 UINT8 *features, UINT32 trusted_mask[],
63 LINK_KEY link_key, UINT8 key_type, tBTM_IO_CAP io_cap,
64 UINT8 pin_length)
65 {
66 tBTM_SEC_DEV_REC *p_dev_rec;
67 int i, j;
68 BOOLEAN found = FALSE;
69
70 BTM_TRACE_API("%s: link key type:%x", __func__, key_type);
71 p_dev_rec = btm_find_dev (bd_addr);
72 if (!p_dev_rec)
73 {
74 if (list_length(btm_cb.sec_dev_rec) > BTM_SEC_MAX_DEVICE_RECORDS) {
75 BTM_TRACE_DEBUG("%s: Max devices reached!", __func__);
76 return FALSE;
77 }
78
79 BTM_TRACE_DEBUG ("%s: allocate a new dev rec", __func__);
80 p_dev_rec = osi_calloc(sizeof(tBTM_SEC_DEV_REC));
81 list_append(btm_cb.sec_dev_rec, p_dev_rec);
82
83 memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
84 p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
85
86 #if BLE_INCLUDED == TRUE
87 /* use default value for background connection params */
88 /* update conn params, use default value for background connection params */
89 memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
90 #endif
91 }
92
93 p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; /* Default value */
94 p_dev_rec->timestamp = btm_cb.dev_rec_count++;
95
96 if (dev_class)
97 memcpy (p_dev_rec->dev_class, dev_class, DEV_CLASS_LEN);
98
99 memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME));
100
101 if (bd_name && bd_name[0])
102 {
103 p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
104 strlcpy ((char *)p_dev_rec->sec_bd_name,
105 (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
106 }
107
108 p_dev_rec->num_read_pages = 0;
109 if (features)
110 {
111 memcpy (p_dev_rec->features, features, sizeof (p_dev_rec->features));
112 for (i = HCI_EXT_FEATURES_PAGE_MAX; i >= 0; i--)
113 {
114 for (j = 0; j < HCI_FEATURE_BYTES_PER_PAGE; j++)
115 {
116 if (p_dev_rec->features[i][j] != 0)
117 {
118 found = TRUE;
119 break;
120 }
121 }
122 if (found)
123 {
124 p_dev_rec->num_read_pages = i + 1;
125 break;
126 }
127 }
128 }
129 else
130 memset (p_dev_rec->features, 0, sizeof (p_dev_rec->features));
131
132 BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
133
134 if (link_key)
135 {
136 BTM_TRACE_EVENT ("%s: BDA: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
137 bd_addr[0], bd_addr[1], bd_addr[2],
138 bd_addr[3], bd_addr[4], bd_addr[5]);
139 p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
140 memcpy (p_dev_rec->link_key, link_key, LINK_KEY_LEN);
141 p_dev_rec->link_key_type = key_type;
142 p_dev_rec->pin_code_length = pin_length;
143
144 if (pin_length >= 16 ||
145 key_type == BTM_LKEY_TYPE_AUTH_COMB ||
146 key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256) {
147 // Set the flag if the link key was made by using either a 16 digit
148 // pin or MITM.
149 p_dev_rec->sec_flags |= BTM_SEC_16_DIGIT_PIN_AUTHED | BTM_SEC_LINK_KEY_AUTHED;
150 }
151 }
152
153 #if defined(BTIF_MIXED_MODE_INCLUDED) && (BTIF_MIXED_MODE_INCLUDED == TRUE)
154 if (key_type < BTM_MAX_PRE_SM4_LKEY_TYPE)
155 p_dev_rec->sm4 = BTM_SM4_KNOWN;
156 else
157 p_dev_rec->sm4 = BTM_SM4_TRUE;
158 #endif
159
160 p_dev_rec->rmt_io_caps = io_cap;
161 p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
162
163 return(TRUE);
164 }
165
166
167 /*******************************************************************************
168 **
169 ** Function BTM_SecDeleteDevice
170 **
171 ** Description Free resources associated with the device.
172 **
173 ** Parameters: bd_addr - BD address of the peer
174 **
175 ** Returns TRUE if removed OK, FALSE if not found or ACL link is active
176 **
177 *******************************************************************************/
BTM_SecDeleteDevice(BD_ADDR bd_addr)178 BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr)
179 {
180 tBTM_SEC_DEV_REC *p_dev_rec;
181
182 if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
183 BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR))
184 {
185 BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active", __func__);
186 return FALSE;
187 }
188
189 if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL)
190 {
191 btm_sec_free_dev(p_dev_rec);
192 /* Tell controller to get rid of the link key, if it has one stored */
193 BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
194 }
195
196 return TRUE;
197 }
198
199 /*******************************************************************************
200 **
201 ** Function BTM_SecReadDevName
202 **
203 ** Description Looks for the device name in the security database for the
204 ** specified BD address.
205 **
206 ** Returns Pointer to the name or NULL
207 **
208 *******************************************************************************/
BTM_SecReadDevName(BD_ADDR bd_addr)209 char *BTM_SecReadDevName (BD_ADDR bd_addr)
210 {
211 char *p_name = NULL;
212 tBTM_SEC_DEV_REC *p_srec;
213
214 if ((p_srec = btm_find_dev(bd_addr)) != NULL)
215 p_name = (char *)p_srec->sec_bd_name;
216
217 return(p_name);
218 }
219
is_bd_addr_equal(void * data,void * context)220 bool is_bd_addr_equal(void *data, void *context)
221 {
222 tBTM_SEC_DEV_REC *p_dev_rec = data;
223 BD_ADDR *bd_addr = context;
224
225 if (!memcmp(p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN))
226 return false;
227
228 return true;
229 }
230
231 /*******************************************************************************
232 **
233 ** Function btm_sec_alloc_dev
234 **
235 ** Description Look for the record in the device database for the record
236 ** with specified address
237 **
238 ** Returns Pointer to the record or NULL
239 **
240 *******************************************************************************/
btm_sec_alloc_dev(BD_ADDR bd_addr)241 tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr)
242 {
243 tBTM_SEC_DEV_REC *p_dev_rec = NULL;
244 tBTM_INQ_INFO *p_inq_info;
245 BTM_TRACE_EVENT ("btm_sec_alloc_dev");
246
247 if (list_length(btm_cb.sec_dev_rec) > BTM_SEC_MAX_DEVICE_RECORDS) {
248 p_dev_rec = btm_find_oldest_dev();
249 } else {
250 BTM_TRACE_DEBUG ("allocate a new dev rec");
251 p_dev_rec = osi_calloc(sizeof(tBTM_SEC_DEV_REC));
252 list_append(btm_cb.sec_dev_rec, p_dev_rec);
253 }
254
255 p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; /* Default value */
256 p_dev_rec->sec_flags = BTM_SEC_IN_USE;
257
258 /* Check with the BT manager if details about remote device are known */
259 /* outgoing connection */
260 if ((p_inq_info = BTM_InqDbRead(bd_addr)) != NULL)
261 {
262 memcpy (p_dev_rec->dev_class, p_inq_info->results.dev_class, DEV_CLASS_LEN);
263
264 #if BLE_INCLUDED == TRUE
265 p_dev_rec->device_type = p_inq_info->results.device_type;
266 p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type;
267 #endif
268 }
269 else if (!memcmp (bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
270 memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
271
272 #if BLE_INCLUDED == TRUE
273 /* update conn params, use default value for background connection params */
274 memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
275 #endif
276
277 memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
278
279 #if BLE_INCLUDED == TRUE
280 p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE);
281 #endif
282 p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
283 p_dev_rec->timestamp = btm_cb.dev_rec_count++;
284
285 return(p_dev_rec);
286 }
287
288
289 /*******************************************************************************
290 **
291 ** Function btm_sec_free_dev
292 **
293 ** Description Mark device record as not used
294 **
295 *******************************************************************************/
btm_sec_free_dev(tBTM_SEC_DEV_REC * p_dev_rec)296 void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec)
297 {
298 p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
299 p_dev_rec->sec_flags = 0;
300
301 #if BLE_INCLUDED == TRUE
302 /* Clear out any saved BLE keys */
303 btm_sec_clear_ble_keys (p_dev_rec);
304 /* clear the ble block */
305 memset(&p_dev_rec->ble, 0, sizeof(tBTM_SEC_BLE));
306 #endif
307
308
309 }
310
311 /*******************************************************************************
312 **
313 ** Function btm_dev_support_switch
314 **
315 ** Description This function is called by the L2CAP to check if remote
316 ** device supports role switch
317 **
318 ** Parameters: bd_addr - Address of the peer device
319 **
320 ** Returns TRUE if device is known and role switch is supported
321 **
322 *******************************************************************************/
btm_dev_support_switch(BD_ADDR bd_addr)323 BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr)
324 {
325 tBTM_SEC_DEV_REC *p_dev_rec;
326 UINT8 xx;
327 BOOLEAN feature_empty = TRUE;
328
329 #if BTM_SCO_INCLUDED == TRUE
330 /* Role switch is not allowed if a SCO is up */
331 if (btm_is_sco_active_by_bdaddr(bd_addr))
332 return(FALSE);
333 #endif
334 p_dev_rec = btm_find_dev (bd_addr);
335 if (p_dev_rec && controller_get_interface()->supports_master_slave_role_switch())
336 {
337 if (HCI_SWITCH_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
338 {
339 BTM_TRACE_DEBUG("btm_dev_support_switch return TRUE (feature found)");
340 return (TRUE);
341 }
342
343 /* If the feature field is all zero, we never received them */
344 for (xx = 0 ; xx < BD_FEATURES_LEN ; xx++)
345 {
346 if (p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0][xx] != 0x00)
347 {
348 feature_empty = FALSE; /* at least one is != 0 */
349 break;
350 }
351 }
352
353 /* If we don't know peer's capabilities, assume it supports Role-switch */
354 if (feature_empty)
355 {
356 BTM_TRACE_DEBUG("btm_dev_support_switch return TRUE (feature empty)");
357 return (TRUE);
358 }
359 }
360
361 BTM_TRACE_DEBUG("btm_dev_support_switch return FALSE");
362 return(FALSE);
363 }
364
is_handle_equal(void * data,void * context)365 bool is_handle_equal(void *data, void *context)
366 {
367 tBTM_SEC_DEV_REC *p_dev_rec = data;
368 UINT16 *handle = context;
369
370 if (p_dev_rec->hci_handle == *handle
371 #if BLE_INCLUDED == TRUE
372 || p_dev_rec->ble_hci_handle == *handle
373 #endif
374 )
375 return false;
376
377 return true;
378 }
379
380 /*******************************************************************************
381 **
382 ** Function btm_find_dev_by_handle
383 **
384 ** Description Look for the record in the device database for the record
385 ** with specified handle
386 **
387 ** Returns Pointer to the record or NULL
388 **
389 *******************************************************************************/
btm_find_dev_by_handle(UINT16 handle)390 tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle)
391 {
392 list_node_t *n = list_foreach(btm_cb.sec_dev_rec, is_handle_equal, &handle);
393 if (n)
394 return list_node(n);
395
396 return NULL;
397 }
398
is_address_equal(void * data,void * context)399 bool is_address_equal(void *data, void *context)
400 {
401 tBTM_SEC_DEV_REC *p_dev_rec = data;
402 BD_ADDR *bd_addr = context;
403
404 if (!memcmp (p_dev_rec->bd_addr, *bd_addr, BD_ADDR_LEN))
405 return false;
406 #if BLE_INCLUDED == TRUE
407 // If a LE random address is looking for device record
408 if (!memcmp(p_dev_rec->ble.pseudo_addr, *bd_addr, BD_ADDR_LEN))
409 return false;
410
411 if (btm_ble_addr_resolvable(*bd_addr, p_dev_rec))
412 return false;
413 #endif
414 return true;
415 }
416
417 /*******************************************************************************
418 **
419 ** Function btm_find_dev
420 **
421 ** Description Look for the record in the device database for the record
422 ** with specified BD address
423 **
424 ** Returns Pointer to the record or NULL
425 **
426 *******************************************************************************/
btm_find_dev(BD_ADDR bd_addr)427 tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr)
428 {
429 if (!bd_addr)
430 return NULL;
431
432 list_node_t *n = list_foreach(btm_cb.sec_dev_rec, is_address_equal, bd_addr);
433 if (n)
434 return list_node(n);
435
436 return NULL;
437 }
438
439 /*******************************************************************************
440 **
441 ** Function btm_consolidate_dev
442 5**
443 ** Description combine security records if identified as same peer
444 **
445 ** Returns none
446 **
447 *******************************************************************************/
btm_consolidate_dev(tBTM_SEC_DEV_REC * p_target_rec)448 void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec)
449 {
450 #if BLE_INCLUDED == TRUE
451 tBTM_SEC_DEV_REC temp_rec = *p_target_rec;
452
453 BTM_TRACE_DEBUG("%s", __func__);
454
455 list_node_t *end = list_end(btm_cb.sec_dev_rec);
456 for (list_node_t *node = list_begin(btm_cb.sec_dev_rec); node != end; node = list_next(node)) {
457 tBTM_SEC_DEV_REC *p_dev_rec = list_node(node);
458
459 if (p_target_rec == p_dev_rec)
460 continue;
461
462 if (!memcmp (p_dev_rec->bd_addr, p_target_rec->bd_addr, BD_ADDR_LEN))
463 {
464 memcpy(p_target_rec, p_dev_rec, sizeof(tBTM_SEC_DEV_REC));
465 p_target_rec->ble = temp_rec.ble;
466 p_target_rec->ble_hci_handle = temp_rec.ble_hci_handle;
467 p_target_rec->enc_key_size = temp_rec.enc_key_size;
468 p_target_rec->conn_params = temp_rec.conn_params;
469 p_target_rec->device_type |= temp_rec.device_type;
470 p_target_rec->sec_flags |= temp_rec.sec_flags;
471
472 p_target_rec->new_encryption_key_is_p256 = temp_rec.new_encryption_key_is_p256;
473 p_target_rec->no_smp_on_br = temp_rec.no_smp_on_br;
474 p_target_rec->bond_type = temp_rec.bond_type;
475
476 /* remove the combined record */
477 list_remove(btm_cb.sec_dev_rec, p_dev_rec);
478
479 p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
480 break;
481 }
482
483 /* an RPA device entry is a duplicate of the target record */
484 if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec))
485 {
486 if (memcmp(p_target_rec->ble.pseudo_addr, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)
487 {
488 p_target_rec->ble.ble_addr_type = p_dev_rec->ble.ble_addr_type;
489 p_target_rec->device_type |= p_dev_rec->device_type;
490
491 /* remove the combined record */
492 list_remove(btm_cb.sec_dev_rec, p_dev_rec);
493
494 p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
495 }
496 break;
497 }
498 }
499 #endif
500 }
501
502 /*******************************************************************************
503 **
504 ** Function btm_find_or_alloc_dev
505 **
506 ** Description Look for the record in the device database for the record
507 ** with specified BD address
508 **
509 ** Returns Pointer to the record or NULL
510 **
511 *******************************************************************************/
btm_find_or_alloc_dev(BD_ADDR bd_addr)512 tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr)
513 {
514 tBTM_SEC_DEV_REC *p_dev_rec;
515 BTM_TRACE_EVENT ("btm_find_or_alloc_dev");
516 if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
517 {
518
519 /* Allocate a new device record or reuse the oldest one */
520 p_dev_rec = btm_sec_alloc_dev (bd_addr);
521 }
522 return(p_dev_rec);
523 }
524
525 /*******************************************************************************
526 **
527 ** Function btm_find_oldest_dev
528 **
529 ** Description Locates the oldest device in use. It first looks for
530 ** the oldest non-paired device. If all devices are paired it
531 ** deletes the oldest paired device.
532 **
533 ** Returns Pointer to the record or NULL
534 **
535 *******************************************************************************/
btm_find_oldest_dev(void)536 tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
537 {
538 tBTM_SEC_DEV_REC *p_oldest = NULL;
539 UINT32 ot = 0xFFFFFFFF;
540 tBTM_SEC_DEV_REC *p_oldest_paired = NULL;
541 UINT32 ot_paired = 0xFFFFFFFF;
542
543 /* First look for the non-paired devices for the oldest entry */
544 list_node_t *end = list_end(btm_cb.sec_dev_rec);
545 for (list_node_t *node = list_begin(btm_cb.sec_dev_rec); node != end; node = list_next(node)) {
546 tBTM_SEC_DEV_REC *p_dev_rec = list_node(node);
547 /* Device is not paired */
548 if ((p_dev_rec->sec_flags & (BTM_SEC_LINK_KEY_KNOWN |BTM_SEC_LE_LINK_KEY_KNOWN)) == 0) {
549 if (p_dev_rec->timestamp < ot) {
550 p_oldest = p_dev_rec;
551 ot = p_dev_rec->timestamp;
552 }
553 continue;
554 }
555
556 if (p_dev_rec->timestamp < ot_paired) {
557 p_oldest_paired = p_dev_rec;
558 ot_paired = p_dev_rec->timestamp;
559 }
560
561 }
562
563 /* if non-paired device return oldest */
564 if (ot != 0xFFFFFFFF)
565 return(p_oldest);
566
567 /* only paired devices present, return oldest */
568 return p_oldest_paired;
569 }
570
571 /*******************************************************************************
572 **
573 ** Function btm_get_bond_type_dev
574 **
575 ** Description Get the bond type for a device in the device database
576 ** with specified BD address
577 **
578 ** Returns The device bond type if known, otherwise BOND_TYPE_UNKNOWN
579 **
580 *******************************************************************************/
btm_get_bond_type_dev(BD_ADDR bd_addr)581 tBTM_BOND_TYPE btm_get_bond_type_dev(BD_ADDR bd_addr)
582 {
583 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bd_addr);
584
585 if (p_dev_rec == NULL)
586 return BOND_TYPE_UNKNOWN;
587
588 return p_dev_rec->bond_type;
589 }
590
591 /*******************************************************************************
592 **
593 ** Function btm_set_bond_type_dev
594 **
595 ** Description Set the bond type for a device in the device database
596 ** with specified BD address
597 **
598 ** Returns TRUE on success, otherwise FALSE
599 **
600 *******************************************************************************/
btm_set_bond_type_dev(BD_ADDR bd_addr,tBTM_BOND_TYPE bond_type)601 BOOLEAN btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type)
602 {
603 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bd_addr);
604
605 if (p_dev_rec == NULL)
606 return FALSE;
607
608 p_dev_rec->bond_type = bond_type;
609 return TRUE;
610 }
611