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 BLE address management.
22 *
23 ******************************************************************************/
24
25 #include <string.h>
26
27 #include "bt_types.h"
28 #include "hcimsgs.h"
29 #include "btu.h"
30 #include "btm_int.h"
31 #include "gap_api.h"
32
33 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
34 #include "btm_ble_int.h"
35 #include "smp_api.h"
36
37 #include "vendor_ble.h"
38
39 /*******************************************************************************
40 **
41 ** Function btm_gen_resolve_paddr_cmpl
42 **
43 ** Description This is callback functioin when resolvable private address
44 ** generation is complete.
45 **
46 ** Returns void
47 **
48 *******************************************************************************/
btm_gen_resolve_paddr_cmpl(tSMP_ENC * p)49 static void btm_gen_resolve_paddr_cmpl(tSMP_ENC *p)
50 {
51 tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
52 BTM_TRACE_EVENT ("btm_gen_resolve_paddr_cmpl");
53
54 if (p)
55 {
56 /* set hash to be LSB of rpAddress */
57 p_cb->private_addr[5] = p->param_buf[0];
58 p_cb->private_addr[4] = p->param_buf[1];
59 p_cb->private_addr[3] = p->param_buf[2];
60 /* set it to controller */
61 btsnd_hcic_ble_set_random_addr(p_cb->private_addr);
62
63 p_cb->own_addr_type = BLE_ADDR_RANDOM;
64
65 /* start a periodical timer to refresh random addr */
66 btu_stop_timer_oneshot(&p_cb->raddr_timer_ent);
67 #if (BTM_BLE_CONFORMANCE_TESTING == TRUE)
68 btu_start_timer_oneshot(&p_cb->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
69 btm_cb.ble_ctr_cb.rpa_tout);
70 #else
71 btu_start_timer_oneshot(&p_cb->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
72 BTM_BLE_PRIVATE_ADDR_INT);
73 #endif
74 }
75 else
76 {
77 /* random address set failure */
78 BTM_TRACE_DEBUG("set random address failed");
79 }
80 }
81 /*******************************************************************************
82 **
83 ** Function btm_gen_resolve_paddr_low
84 **
85 ** Description This function is called when random address has generate the
86 ** random number base for low 3 byte bd address.
87 **
88 ** Returns void
89 **
90 *******************************************************************************/
btm_gen_resolve_paddr_low(tBTM_RAND_ENC * p)91 void btm_gen_resolve_paddr_low(tBTM_RAND_ENC *p)
92 {
93 #if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
94 tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
95 tSMP_ENC output;
96
97 BTM_TRACE_EVENT ("btm_gen_resolve_paddr_low");
98 if (p)
99 {
100 p->param_buf[2] &= (~BLE_RESOLVE_ADDR_MASK);
101 p->param_buf[2] |= BLE_RESOLVE_ADDR_MSB;
102
103 p_cb->private_addr[2] = p->param_buf[0];
104 p_cb->private_addr[1] = p->param_buf[1];
105 p_cb->private_addr[0] = p->param_buf[2];
106
107 /* encrypt with ur IRK */
108 if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, p->param_buf, 3, &output))
109 {
110 btm_gen_resolve_paddr_cmpl(NULL);
111 }
112 else
113 {
114 btm_gen_resolve_paddr_cmpl(&output);
115 }
116 }
117 #endif
118 }
119 /*******************************************************************************
120 **
121 ** Function btm_gen_resolvable_private_addr
122 **
123 ** Description This function generate a resolvable private address.
124 **
125 ** Returns void
126 **
127 *******************************************************************************/
btm_gen_resolvable_private_addr(void * p_cmd_cplt_cback)128 void btm_gen_resolvable_private_addr (void *p_cmd_cplt_cback)
129 {
130 BTM_TRACE_EVENT ("btm_gen_resolvable_private_addr");
131 /* generate 3B rand as BD LSB, SRK with it, get BD MSB */
132 if (!btsnd_hcic_ble_rand((void *)p_cmd_cplt_cback))
133 btm_gen_resolve_paddr_cmpl(NULL);
134 }
135 /*******************************************************************************
136 **
137 ** Function btm_gen_non_resolve_paddr_cmpl
138 **
139 ** Description This is the callback function when non-resolvable private
140 ** function is generated and write to controller.
141 **
142 ** Returns void
143 **
144 *******************************************************************************/
btm_gen_non_resolve_paddr_cmpl(tBTM_RAND_ENC * p)145 static void btm_gen_non_resolve_paddr_cmpl(tBTM_RAND_ENC *p)
146 {
147 tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
148 tBTM_BLE_ADDR_CBACK *p_cback = p_cb->p_generate_cback;
149 void *p_data = p_cb->p;
150 UINT8 *pp;
151 BD_ADDR static_random;
152
153 BTM_TRACE_EVENT ("btm_gen_non_resolve_paddr_cmpl");
154
155 p_cb->p_generate_cback = NULL;
156 if (p)
157 {
158
159 pp = p->param_buf;
160 STREAM_TO_BDADDR(static_random, pp);
161 /* mask off the 2 MSB */
162 static_random[0] &= BLE_STATIC_PRIVATE_MSB_MASK;
163
164 /* report complete */
165 if (p_cback)
166 (* p_cback)(static_random, p_data);
167 }
168 else
169 {
170 BTM_TRACE_DEBUG("btm_gen_non_resolvable_private_addr failed");
171 if (p_cback)
172 (* p_cback)(NULL, p_data);
173 }
174 }
175 /*******************************************************************************
176 **
177 ** Function btm_gen_non_resolvable_private_addr
178 **
179 ** Description This function generate a non-resolvable private address.
180 **
181 **
182 ** Returns void
183 **
184 *******************************************************************************/
btm_gen_non_resolvable_private_addr(tBTM_BLE_ADDR_CBACK * p_cback,void * p)185 void btm_gen_non_resolvable_private_addr (tBTM_BLE_ADDR_CBACK *p_cback, void *p)
186 {
187 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
188
189 BTM_TRACE_EVENT ("btm_gen_non_resolvable_private_addr");
190
191 if (p_mgnt_cb->p_generate_cback != NULL)
192 return;
193
194 p_mgnt_cb->p_generate_cback = p_cback;
195 p_mgnt_cb->p = p;
196 if (!btsnd_hcic_ble_rand((void *)btm_gen_non_resolve_paddr_cmpl))
197 {
198 btm_gen_non_resolve_paddr_cmpl(NULL);
199 }
200
201 }
202 #if SMP_INCLUDED == TRUE
203 /*******************************************************************************
204 ** Utility functions for Random address resolving
205 *******************************************************************************/
206 /*******************************************************************************
207 **
208 ** Function btm_ble_resolve_address_cmpl
209 **
210 ** Description This function sends the random address resolving complete
211 ** callback.
212 **
213 ** Returns None.
214 **
215 *******************************************************************************/
btm_ble_resolve_address_cmpl(void)216 static void btm_ble_resolve_address_cmpl(void)
217 {
218 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
219 tBTM_SEC_DEV_REC *p_dev_rec = NULL;
220
221 BTM_TRACE_EVENT ("btm_ble_resolve_address_cmpl p_mgnt_cb->index = %d", p_mgnt_cb->index);
222
223 if (p_mgnt_cb->index < BTM_SEC_MAX_DEVICE_RECORDS)
224 {
225 p_dev_rec = &btm_cb.sec_dev_rec[p_mgnt_cb->index];
226 }
227
228 p_mgnt_cb->busy = FALSE;
229
230 (* p_mgnt_cb->p_resolve_cback)(p_dev_rec, p_mgnt_cb->p);
231 }
232 /*******************************************************************************
233 **
234 ** Function btm_ble_proc_resolve_x
235 **
236 ** Description This function compares the X with random address 3 MSO bytes
237 ** to find a match, if not match, continue for next record.
238 **
239 ** Returns None.
240 **
241 *******************************************************************************/
btm_ble_proc_resolve_x(tSMP_ENC * p)242 static BOOLEAN btm_ble_proc_resolve_x(tSMP_ENC *p)
243 {
244 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
245 UINT8 comp[3];
246 BTM_TRACE_EVENT ("btm_ble_proc_resolve_x");
247 /* compare the hash with 3 LSB of bd address */
248 comp[0] = p_mgnt_cb->random_bda[5];
249 comp[1] = p_mgnt_cb->random_bda[4];
250 comp[2] = p_mgnt_cb->random_bda[3];
251
252 if (p)
253 {
254 if (!memcmp(p->param_buf, &comp[0], 3))
255 {
256 /* match is found */
257 BTM_TRACE_EVENT ("match is found");
258 btm_ble_resolve_address_cmpl();
259 return TRUE;
260 }
261 }
262 return FALSE;
263 }
264 /*******************************************************************************
265 **
266 ** Function btm_ble_match_random_bda
267 **
268 ** Description This function match the random address to the appointed device
269 ** record, starting from calculating IRK. If record index exceed
270 ** the maximum record number, matching failed and send callback.
271 **
272 ** Returns None.
273 **
274 *******************************************************************************/
btm_ble_match_random_bda(UINT16 rec_index)275 static BOOLEAN btm_ble_match_random_bda(UINT16 rec_index)
276 {
277 #if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
278 tBTM_SEC_DEV_REC *p_dev_rec;
279 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
280 UINT8 rand[3];
281 tSMP_ENC output;
282
283 /* use the 3 MSB of bd address as prand */
284 rand[0] = p_mgnt_cb->random_bda[2];
285 rand[1] = p_mgnt_cb->random_bda[1];
286 rand[2] = p_mgnt_cb->random_bda[0];
287
288 BTM_TRACE_EVENT("btm_ble_match_random_bda rec_index = %d", rec_index);
289
290 if (rec_index < BTM_SEC_MAX_DEVICE_RECORDS)
291 {
292 p_dev_rec = &btm_cb.sec_dev_rec[rec_index];
293
294 BTM_TRACE_DEBUG("sec_flags = %02x device_type = %d", p_dev_rec->sec_flags, p_dev_rec->device_type);
295
296 if ((p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) &&
297 (p_dev_rec->ble.key_type & BTM_LE_KEY_PID))
298 {
299 /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */
300 SMP_Encrypt(p_dev_rec->ble.keys.irk, BT_OCTET16_LEN,
301 &rand[0], 3, &output);
302 return btm_ble_proc_resolve_x(&output);
303 }
304 else
305 {
306 // not completed
307 return FALSE;
308 }
309 }
310 else /* no match found */
311 {
312 btm_ble_resolve_address_cmpl();
313 return TRUE;
314 }
315 #endif
316 }
317
318 /*******************************************************************************
319 **
320 ** Function btm_ble_resolve_random_addr
321 **
322 ** Description This function is called to resolve a random address.
323 **
324 ** Returns pointer to the security record of the device whom a random
325 ** address is matched to.
326 **
327 *******************************************************************************/
btm_ble_resolve_random_addr(BD_ADDR random_bda,tBTM_BLE_RESOLVE_CBACK * p_cback,void * p)328 void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK * p_cback, void *p)
329 {
330 tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
331
332 BTM_TRACE_EVENT ("btm_ble_resolve_random_addr");
333 if ( !p_mgnt_cb->busy)
334 {
335 p_mgnt_cb->p = p;
336 p_mgnt_cb->busy = TRUE;
337 p_mgnt_cb->index = 0;
338 p_mgnt_cb->p_resolve_cback = p_cback;
339 memcpy(p_mgnt_cb->random_bda, random_bda, BD_ADDR_LEN);
340 /* start to resolve random address */
341 /* check for next security record */
342 while (TRUE)
343 {
344 if (btm_ble_match_random_bda(p_mgnt_cb->index))
345 {
346 /* atch found or went through the list */
347 break;
348 }
349 p_mgnt_cb->index ++;
350 }
351 }
352 else
353 (*p_cback)(NULL, p);
354 }
355 #endif
356 /*******************************************************************************
357 ** address mapping between pseudo address and real connection address
358 *******************************************************************************/
359 /*******************************************************************************
360 **
361 ** Function btm_ble_map_bda_to_conn_bda
362 **
363 ** Description This function map a BD address to the real connection address
364 ** and return the connection address type.
365 *******************************************************************************/
btm_ble_map_bda_to_conn_bda(BD_ADDR bd_addr)366 tBLE_ADDR_TYPE btm_ble_map_bda_to_conn_bda(BD_ADDR bd_addr)
367 {
368 tBTM_SEC_DEV_REC *p_dev_rec = NULL;
369 BTM_TRACE_EVENT ("btm_ble_map_bda_to_conn_bda");
370 if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL &&
371 p_dev_rec->device_type == BT_DEVICE_TYPE_BLE)
372 {
373 if (p_dev_rec->ble.ble_addr_type != BLE_ADDR_PUBLIC)
374 {
375 memcpy(bd_addr, p_dev_rec->ble.static_addr, BD_ADDR_LEN);
376 }
377 return p_dev_rec->ble.ble_addr_type;
378 }
379 else
380 return BLE_ADDR_PUBLIC;
381 }
382
383 /*******************************************************************************
384 **
385 ** Function btm_find_dev_by_public_static_addr
386 **
387 ** Description find the security record whose LE static address is matching
388 **
389 *******************************************************************************/
btm_find_dev_by_public_static_addr(BD_ADDR bd_addr)390 tBTM_SEC_DEV_REC* btm_find_dev_by_public_static_addr(BD_ADDR bd_addr)
391 {
392 UINT8 i;
393 tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
394 #if BLE_PRIVACY_SPT == TRUE
395 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev_rec ++)
396 {
397 if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_RANDOM &&
398 BTM_BLE_IS_RESOLVE_BDA(p_dev_rec->bd_addr))
399 {
400 if ( memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) == 0)
401 {
402 p_dev_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
403 /* found the match */
404 return p_dev_rec;
405 }
406 }
407 }
408 #endif
409 return NULL;
410 }
411
412 /*******************************************************************************
413 **
414 ** Function btm_public_addr_to_random_pseudo
415 **
416 ** Description This function map a static BD address to a pseudo random address
417 ** in security database.
418 **
419 *******************************************************************************/
btm_public_addr_to_random_pseudo(BD_ADDR bd_addr,UINT8 * p_addr_type)420 BOOLEAN btm_public_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type)
421 {
422 #if BLE_PRIVACY_SPT == TRUE
423 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_public_static_addr(bd_addr);
424
425 BTM_TRACE_EVENT ("btm_public_addr_to_random_pseudo");
426
427 /* evt reported on static address, map static address to random pseudo */
428 if (p_dev_rec != NULL &&
429 /* static address is not static address */
430 memcmp(p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN) != 0)
431 /* update current random */
432 btm_ble_read_irk_entry(p_dev_rec->ble.static_addr);
433 if (p_dev_rec != NULL)
434 {
435 /* assign the orginal random to be the current report address */
436 memcpy(bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
437 /* always be a resolvable random if a match is found */
438 *p_addr_type = BLE_ADDR_RANDOM;
439
440 BTM_TRACE_ERROR("matched a public/reconnect address and map to random pseudo");
441
442 return TRUE;
443 }
444 #endif
445 return FALSE;
446 }
447
448 /*******************************************************************************
449 **
450 ** Function btm_random_pseudo_to_public
451 **
452 ** Description This function map a random pseudo address to a public address
453 ** random_pseudo is input and output parameter
454 **
455 *******************************************************************************/
btm_random_pseudo_to_public(BD_ADDR random_pseudo,UINT8 * p_static_addr_type)456 BOOLEAN btm_random_pseudo_to_public(BD_ADDR random_pseudo, UINT8 *p_static_addr_type)
457 {
458 #if BLE_PRIVACY_SPT == TRUE
459 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (random_pseudo);
460
461 if (p_dev_rec != NULL)
462 {
463 if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_RANDOM &&
464 BTM_BLE_IS_RESOLVE_BDA(p_dev_rec->bd_addr) &&
465 (p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0)
466 {
467 BTM_TRACE_EVENT ("btm_random_pseudo_to_public found the puclic static address!");
468 * p_static_addr_type = p_dev_rec->ble.static_addr_type;
469 memcpy(random_pseudo, p_dev_rec->ble.static_addr, BD_ADDR_LEN);
470 return TRUE;
471 }
472 }
473 #endif
474 return FALSE;
475 }
476
477 /*******************************************************************************
478 **
479 ** Function btm_ble_refresh_rra
480 **
481 ** Description This function refresh the currently used RRA into security
482 ** database and set active connection address.
483 **
484 *******************************************************************************/
btm_ble_refresh_rra(BD_ADDR static_bda,BD_ADDR rra)485 void btm_ble_refresh_rra(BD_ADDR static_bda, BD_ADDR rra)
486 {
487 #if BLE_PRIVACY_SPT == TRUE
488 tBTM_SEC_DEV_REC *p_sec_rec = btm_find_dev_by_public_static_addr(static_bda);
489 tACL_CONN *p_acl = btm_bda_to_acl (p_sec_rec->bd_addr, BT_TRANSPORT_LE);
490 UINT8 rra_dummy = FALSE;
491 BD_ADDR dummy_bda = {0};
492
493 BTM_TRACE_ERROR("btm_ble_refresh_rra");
494
495 if (memcmp(dummy_bda, rra, BD_ADDR_LEN) == 0)
496 rra_dummy = TRUE;
497
498 /* connection refresh RRA */
499 if (p_acl != NULL /* && memcmp(p_acl->active_remote_addr, dummy_bda, BD_ADDR_LEN) == 0 */)
500 {
501 /* use static address, rra is empty */
502 if (rra_dummy)
503 {
504 p_acl->active_remote_addr_type = p_sec_rec->ble.static_addr_type;
505 memcpy(p_acl->active_remote_addr, p_sec_rec->ble.static_addr, BD_ADDR_LEN);
506 }
507 else
508 {
509 p_acl->active_remote_addr_type = BLE_ADDR_RANDOM;
510 memcpy(p_acl->active_remote_addr, rra, BD_ADDR_LEN);
511 }
512 }
513 /* update security record here, in adv event or connection complete process */
514 if (p_sec_rec != NULL)
515 {
516 memcpy(p_sec_rec->ble.cur_rand_addr, rra, BD_ADDR_LEN);
517 p_sec_rec->ble.active_addr_type = rra_dummy ? BTM_BLE_ADDR_STATIC: BTM_BLE_ADDR_RRA;
518 }
519 else
520 {
521 BTM_TRACE_ERROR("No matching known device in record");
522 }
523 #endif
524 }
525 #endif
526
527
528