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 device control utilities, and LE
22 *  security functions.
23 *
24 ******************************************************************************/
25
26#include <string.h>
27
28#include "bt_types.h"
29#include "hcimsgs.h"
30#include "btu.h"
31#include "btm_int.h"
32#include "btm_ble_api.h"
33#include "smp_api.h"
34
35#if SMP_INCLUDED == TRUE
36extern BOOLEAN AES_CMAC ( BT_OCTET16 key, UINT8 *input, UINT16 length, UINT16 tlen, UINT8 *p_signature);
37extern void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable);
38extern BOOLEAN smp_proc_ltk_request(BD_ADDR bda);
39#endif
40
41static void btm_ble_update_active_bgconn_scan_params(void);
42
43/*******************************************************************************/
44/* External Function to be called by other modules                             */
45/*******************************************************************************/
46/********************************************************
47**
48** Function         BTM_SecAddBleDevice
49**
50** Description      Add/modify device.  This function will be normally called
51**                  during host startup to restore all required information
52**                  for a LE device stored in the NVRAM.
53**
54** Parameters:      bd_addr          - BD address of the peer
55**                  bd_name          - Name of the peer device.  NULL if unknown.
56**                  dev_type         - Remote device's device type.
57**                  addr_type        - LE device address type.
58**
59** Returns          TRUE if added OK, else FALSE
60**
61*******************************************************************************/
62BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE dev_type,
63                             tBLE_ADDR_TYPE addr_type)
64{
65#if BLE_INCLUDED == TRUE
66    tBTM_SEC_DEV_REC  *p_dev_rec;
67    UINT8               i = 0;
68    tBTM_INQ_INFO      *p_info=NULL;
69
70    BTM_TRACE_DEBUG1 ("BTM_SecAddBleDevice dev_type=0x%x", dev_type);
71    p_dev_rec = btm_find_dev (bd_addr);
72
73    if (!p_dev_rec)
74    {
75        BTM_TRACE_DEBUG0("Add a new device");
76
77        /* There is no device record, allocate one.
78         * If we can not find an empty spot for this one, let it fail. */
79        for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++)
80        {
81            if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE))
82            {
83                BTM_TRACE_DEBUG1 ("allocate a new dev rec idx=0x%x ", i );
84                p_dev_rec = &btm_cb.sec_dev_rec[i];
85
86                /* Mark this record as in use and initialize */
87                memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
88                p_dev_rec->sec_flags = BTM_SEC_IN_USE;
89                memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
90                p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr);
91
92                /* update conn params, use default value for background connection params */
93                p_dev_rec->conn_params.min_conn_int     =
94                p_dev_rec->conn_params.max_conn_int     =
95                p_dev_rec->conn_params.supervision_tout =
96                p_dev_rec->conn_params.slave_latency    = BTM_BLE_CONN_PARAM_UNDEF;
97
98                BTM_TRACE_DEBUG1 ("hci_handl=0x%x ",  p_dev_rec->hci_handle );
99                break;
100            }
101        }
102
103        if (!p_dev_rec)
104            return(FALSE);
105    }
106    else
107    {
108        BTM_TRACE_DEBUG0("Device already exist");
109    }
110
111    memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME));
112
113    if (bd_name && bd_name[0])
114    {
115        p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
116        BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name),
117            (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
118    }
119    p_dev_rec->device_type = dev_type;
120    p_dev_rec->ble.ble_addr_type = addr_type;
121    BTM_TRACE_DEBUG3 ("p_dev_rec->device_type =0x%x  addr_type=0x%x sec_flags=0x%x",
122                      dev_type,  addr_type, p_dev_rec->sec_flags);
123
124    /* sync up with the Inq Data base*/
125    p_info = BTM_InqDbRead(bd_addr);
126    if (p_info)
127    {
128        p_info->results.ble_addr_type = p_dev_rec->ble.ble_addr_type ;
129        p_info->results.device_type = p_dev_rec->device_type;
130        BTM_TRACE_DEBUG2 ("InqDb  device_type =0x%x  addr_type=0x%x",
131                          p_info->results.device_type, p_info->results.ble_addr_type);
132    }
133
134#endif
135    return(TRUE);
136}
137
138/*******************************************************************************
139**
140** Function         BTM_SecAddBleKey
141**
142** Description      Add/modify LE device information.  This function will be
143**                  normally called during host startup to restore all required
144**                  information stored in the NVRAM.
145**
146** Parameters:      bd_addr          - BD address of the peer
147**                  p_le_key         - LE key values.
148**                  key_type         - LE SMP key type.
149*
150** Returns          TRUE if added OK, else FALSE
151**
152*******************************************************************************/
153BOOLEAN BTM_SecAddBleKey (BD_ADDR bd_addr, tBTM_LE_KEY_VALUE *p_le_key, tBTM_LE_KEY_TYPE key_type)
154{
155#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
156    tBTM_SEC_DEV_REC  *p_dev_rec;
157    BTM_TRACE_DEBUG0 ("BTM_SecAddBleKey");
158    p_dev_rec = btm_find_dev (bd_addr);
159    if (!p_dev_rec || !p_le_key ||
160        (key_type != BTM_LE_KEY_PENC && key_type != BTM_LE_KEY_PID &&
161         key_type != BTM_LE_KEY_PCSRK && key_type != BTM_LE_KEY_LENC))
162    {
163        BTM_TRACE_WARNING3 ("BTM_SecAddLeKey()  No BT Link Key, Wrong Type, or No Device record \
164                        for bdaddr: %08x%04x, Type: %d",
165                            (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
166                            (bd_addr[4]<<8)+bd_addr[5], key_type);
167        return(FALSE);
168    }
169
170    BTM_TRACE_DEBUG3 ("BTM_SecAddLeKey()  BDA: %08x%04x, Type: 0x%02x",
171                      (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
172                      (bd_addr[4]<<8)+bd_addr[5], key_type);
173
174    if (key_type == BTM_LE_KEY_PENC || key_type == BTM_LE_KEY_PID ||
175        key_type == BTM_LE_KEY_PCSRK || key_type == BTM_LE_KEY_LENC ||
176        key_type == BTM_LE_KEY_LCSRK)
177    {
178        btm_sec_save_le_key (bd_addr, key_type, p_le_key, FALSE);
179    }
180
181#endif
182
183    return(TRUE);
184}
185
186/*******************************************************************************
187**
188** Function         BTM_BleLoadLocalKeys
189**
190** Description      Local local identity key, encryption root or sign counter.
191**
192** Parameters:      key_type: type of key, can be BTM_BLE_KEY_TYPE_ID, BTM_BLE_KEY_TYPE_ER
193**                            or BTM_BLE_KEY_TYPE_COUNTER.
194**                  p_key: pointer to the key.
195*
196** Returns          non2.
197**
198*******************************************************************************/
199void BTM_BleLoadLocalKeys(UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
200{
201#if BLE_INCLUDED == TRUE
202    tBTM_DEVCB *p_devcb = &btm_cb.devcb;
203    BTM_TRACE_DEBUG0 ("BTM_BleLoadLocalKeys");
204    if (p_key != NULL)
205    {
206        switch (key_type)
207        {
208            case BTM_BLE_KEY_TYPE_ID:
209                memcpy(&p_devcb->id_keys, &p_key->id_keys, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
210                break;
211
212            case BTM_BLE_KEY_TYPE_ER:
213                memcpy(p_devcb->er, p_key->er, sizeof(BT_OCTET16));
214                break;
215
216            default:
217                BTM_TRACE_ERROR1("unknow local key type: %d", key_type);
218                break;
219        }
220    }
221#endif
222}
223
224/*******************************************************************************
225**
226** Function         BTM_GetDeviceEncRoot
227**
228** Description      This function is called to read the local device encryption
229**                  root.
230**
231** Returns          void
232**                  the local device ER is copied into er
233**
234*******************************************************************************/
235void BTM_GetDeviceEncRoot (BT_OCTET16 er)
236{
237    BTM_TRACE_DEBUG0 ("BTM_GetDeviceEncRoot");
238
239#if BLE_INCLUDED == TRUE
240    memcpy (er, btm_cb.devcb.er, BT_OCTET16_LEN);
241#endif
242}
243
244/*******************************************************************************
245**
246** Function         BTM_GetDeviceIDRoot
247**
248** Description      This function is called to read the local device identity
249**                  root.
250**
251** Returns          void
252**                  the local device IR is copied into irk
253**
254*******************************************************************************/
255void BTM_GetDeviceIDRoot (BT_OCTET16 irk)
256{
257    BTM_TRACE_DEBUG0 ("BTM_GetDeviceIDRoot ");
258
259#if BLE_INCLUDED == TRUE
260    memcpy (irk, btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN);
261#endif
262}
263
264/*******************************************************************************
265**
266** Function         BTM_GetDeviceDHK
267**
268** Description      This function is called to read the local device DHK.
269**
270** Returns          void
271**                  the local device DHK is copied into dhk
272**
273*******************************************************************************/
274void BTM_GetDeviceDHK (BT_OCTET16 dhk)
275{
276#if BLE_INCLUDED == TRUE
277    BTM_TRACE_DEBUG0 ("BTM_GetDeviceDHK");
278    memcpy (dhk, btm_cb.devcb.id_keys.dhk, BT_OCTET16_LEN);
279#endif
280}
281
282/*******************************************************************************
283**
284** Function         BTM_ReadConnectionAddr
285**
286** Description      This function is called to set the local device random address
287**                  .
288**
289** Returns          void
290**
291*******************************************************************************/
292void BTM_ReadConnectionAddr (BD_ADDR conn_addr)
293{
294#if BLE_INCLUDED == TRUE
295    BTM_TRACE_DEBUG0 ("BTM_ReadConnectionAddr");
296    if (btm_cb.ble_ctr_cb.inq_var.own_addr_type == BLE_ADDR_PUBLIC)
297    {
298        BTM_GetLocalDeviceAddr(conn_addr);
299    }
300    else
301    {
302        memcpy (conn_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, BD_ADDR_LEN);
303    }
304#endif
305}
306
307/*******************************************************************************
308**
309** Function         BTM_SecurityGrant
310**
311** Description      This function is called to grant security process.
312**
313** Parameters       bd_addr - peer device bd address.
314**                  res     - result of the operation BTM_SUCCESS if success.
315**                            Otherwise, BTM_REPEATED_ATTEMPTS is too many attempts.
316**
317** Returns          None
318**
319*******************************************************************************/
320void BTM_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
321{
322#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
323    tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_REPEATED_ATTEMPTS;
324    BTM_TRACE_DEBUG0 ("BTM_SecurityGrant");
325    SMP_SecurityGrant(bd_addr, res_smp);
326#endif
327}
328
329/*******************************************************************************
330**
331** Function         BTM_BlePasskeyReply
332**
333** Description      This function is called after Security Manager submitted
334**                  passkey request to the application.
335**
336** Parameters:      bd_addr      - Address of the device for which passkey was requested
337**                  res          - result of the operation BTM_SUCCESS if success
338**                  key_len      - length in bytes of the Passkey
339**                  p_passkey        - pointer to array with the passkey
340**                  trusted_mask - bitwise OR of trusted services (array of UINT32)
341**
342*******************************************************************************/
343void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
344{
345#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
346    tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
347    tSMP_STATUS      res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_PASSKEY_ENTRY_FAIL;
348
349    p_dev_rec->sec_flags   |= BTM_SEC_LINK_KEY_AUTHED;
350    BTM_TRACE_DEBUG0 ("BTM_BlePasskeyReply");
351    SMP_PasskeyReply(bd_addr, res_smp, passkey);
352#endif
353}
354
355/*******************************************************************************
356**
357** Function         BTM_BleOobDataReply
358**
359** Description      This function is called to provide the OOB data for
360**                  SMP in response to BTM_LE_OOB_REQ_EVT
361**
362** Parameters:      bd_addr     - Address of the peer device
363**                  res         - result of the operation SMP_SUCCESS if success
364**                  p_data      - simple pairing Randomizer  C.
365**
366*******************************************************************************/
367void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data)
368{
369#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
370    tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_OOB_FAIL;
371    tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
372
373    BTM_TRACE_DEBUG0 ("BTM_BleOobDataReply");
374    p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
375    SMP_OobDataReply(bd_addr, res_smp, len, p_data);
376#endif
377}
378
379/******************************************************************************
380**
381** Function         BTM_BleSetConnScanParams
382**
383** Description      Set scan parameter used in BLE connection request
384**
385** Parameters:      scan_interval: scan interval
386**                  scan_window: scan window
387**
388** Returns          void
389**
390*******************************************************************************/
391void BTM_BleSetConnScanParams (UINT16 scan_interval, UINT16 scan_window)
392{
393#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
394    tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
395    BOOLEAN     new_param = FALSE;
396
397    if (BTM_BLE_VALID_PRAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) &&
398        BTM_BLE_VALID_PRAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX))
399    {
400        btu_stop_timer(&p_ble_cb->scan_param_idle_timer);
401
402        if (p_ble_cb->scan_int != scan_interval)
403        {
404            p_ble_cb->scan_int = scan_interval;
405            new_param = TRUE;
406        }
407
408        if (p_ble_cb->scan_win != scan_window)
409        {
410            p_ble_cb->scan_win = scan_window;
411            new_param = TRUE;
412        }
413
414        if (new_param)
415            btm_ble_update_active_bgconn_scan_params();
416    }
417    else
418    {
419        BTM_TRACE_ERROR0("Illegal Connection Scan Parameters");
420    }
421#endif
422}
423
424/********************************************************
425**
426** Function         BTM_BleSetPrefConnParams
427**
428** Description      Set a peripheral's preferred connection parameters
429**
430** Parameters:      bd_addr          - BD address of the peripheral
431**                  scan_interval: scan interval
432**                  scan_window: scan window
433**                  min_conn_int     - minimum preferred connection interval
434**                  max_conn_int     - maximum preferred connection interval
435**                  slave_latency    - preferred slave latency
436**                  supervision_tout - preferred supervision timeout
437**
438** Returns          void
439**
440*******************************************************************************/
441void BTM_BleSetPrefConnParams (BD_ADDR bd_addr,
442                               UINT16 min_conn_int, UINT16 max_conn_int,
443                               UINT16 slave_latency, UINT16 supervision_tout)
444{
445#if BLE_INCLUDED == TRUE
446    tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
447
448    BTM_TRACE_API4 ("BTM_BleSetPrefConnParams min: %u  max: %u  latency: %u  \
449                    tout: %u",
450                    min_conn_int, max_conn_int, slave_latency, supervision_tout);
451
452    if (BTM_BLE_VALID_PRAM(min_conn_int, BTM_BLE_CONN_INT_MIN, BTM_BLE_CONN_INT_MAX) &&
453        BTM_BLE_VALID_PRAM(max_conn_int, BTM_BLE_CONN_INT_MIN, BTM_BLE_CONN_INT_MAX) &&
454        BTM_BLE_VALID_PRAM(supervision_tout, BTM_BLE_CONN_SUP_TOUT_MIN, BTM_BLE_CONN_SUP_TOUT_MAX) &&
455        slave_latency <= BTM_BLE_CONN_LATENCY_MAX)
456    {
457        if (p_dev_rec)
458        {
459            /* expect conn int and stout and slave latency to be updated all together */
460            if (min_conn_int != BTM_BLE_CONN_PARAM_UNDEF || max_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
461            {
462                if (min_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
463                    p_dev_rec->conn_params.min_conn_int = min_conn_int;
464                else
465                    p_dev_rec->conn_params.min_conn_int = max_conn_int;
466
467                if (max_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
468                    p_dev_rec->conn_params.max_conn_int = max_conn_int;
469                else
470                    p_dev_rec->conn_params.max_conn_int = min_conn_int;
471
472                if (slave_latency != BTM_BLE_CONN_PARAM_UNDEF)
473                    p_dev_rec->conn_params.slave_latency = slave_latency;
474                else
475                    p_dev_rec->conn_params.slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF;
476
477                if (supervision_tout != BTM_BLE_CONN_PARAM_UNDEF)
478                    p_dev_rec->conn_params.supervision_tout = supervision_tout;
479                else
480                    p_dev_rec->conn_params.slave_latency = BTM_BLE_CONN_TIMEOUT_DEF;
481
482            }
483
484        }
485        else
486        {
487            BTM_TRACE_ERROR0("Unknown Device, setting rejected");
488        }
489    }
490    else
491    {
492        BTM_TRACE_ERROR0("Illegal Connection Parameters");
493    }
494#endif  /* BLE_INCLUDED */
495}
496
497/*******************************************************************************
498**
499** Function         BTM_ReadDevInfo
500**
501** Description      This function is called to read the device/address type
502**                  of BD address.
503**
504** Parameter        remote_bda: remote device address
505**                  p_dev_type: output parameter to read the device type.
506**                  p_addr_type: output parameter to read the address type.
507**
508*******************************************************************************/
509void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR_TYPE *p_addr_type)
510{
511#if BLE_INCLUDED == TRUE
512    tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (remote_bda);
513    tBTM_INQ_INFO     *p_inq_info = BTM_InqDbRead(remote_bda);
514
515    *p_dev_type = BT_DEVICE_TYPE_BREDR;
516    *p_addr_type = BLE_ADDR_PUBLIC;
517
518    if (!p_dev_rec)
519    {
520        /* Check with the BT manager if details about remote device are known */
521        if (p_inq_info != NULL)
522        {
523            *p_dev_type = p_inq_info->results.device_type ;
524            *p_addr_type = p_inq_info->results.ble_addr_type;
525        }
526        /* unknown device, assume BR/EDR */
527    }
528    else /* there is a security device record exisitng */
529    {
530        /* new inquiry result, overwrite device type in security device record */
531        if (p_inq_info)
532        {
533            p_dev_rec->device_type          = p_inq_info->results.device_type;
534            p_dev_rec->ble.ble_addr_type    = p_inq_info->results.ble_addr_type;
535        }
536        *p_dev_type = p_dev_rec->device_type;
537        *p_addr_type = p_dev_rec->ble.ble_addr_type;
538
539    }
540
541    BTM_TRACE_DEBUG2 ("btm_find_dev_type - device_type = %d addr_type = %d", *p_dev_type , *p_addr_type);
542#endif
543
544    return;
545}
546
547
548/*******************************************************************************
549** Internal Functions
550*******************************************************************************/
551#if BLE_INCLUDED == TRUE
552
553/*******************************************************************************
554**
555** Function         btm_ble_update_active_bgconn_scan_params
556**
557** Description      This function is called to update the scan parameter if background
558**                  connection has been active.
559**
560*******************************************************************************/
561static void btm_ble_update_active_bgconn_scan_params(void)
562{
563    tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
564    tBTM_BLE_SEL_CBACK   *p_select_cback;
565
566    /* if active , cancel and restart and apply the params */
567    if (p_cb->bg_conn_state == BLE_BG_CONN_ACTIVE)
568    {
569        if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO)
570        {
571            if (btm_ble_start_auto_conn(FALSE))
572                btm_ble_start_auto_conn(TRUE);
573        }
574        else if (p_cb->bg_conn_type == BTM_BLE_CONN_SELECTIVE)
575        {
576            p_select_cback = p_cb->p_select_cback;
577            if (btm_ble_start_select_conn(FALSE, NULL))
578                btm_ble_start_select_conn(TRUE, p_select_cback);
579        }
580    }
581    return;
582}
583
584/*******************************************************************************
585**
586** Function         btm_ble_check_link_type
587**
588** Description      This function is to check the link type is BLE or BR/EDR.
589**
590** Returns          TRUE if BLE link; FALSE if BR/EDR.
591**
592*******************************************************************************/
593BOOLEAN btm_ble_check_link_type (BD_ADDR bd_addr)
594{
595    tACL_CONN         *p;
596    BTM_TRACE_DEBUG0 ("btm_ble_check_link_type");
597    if ((p = btm_bda_to_acl(bd_addr)) != NULL)
598        return p->is_le_link;
599    else
600        return FALSE;
601}
602
603/*******************************************************************************
604**
605** Function         btm_ble_rand_enc_complete
606**
607** Description      This function is the callback functions for HCI_Rand command
608**                  and HCI_Encrypt command is completed.
609**                  This message is received from the HCI.
610**
611** Returns          void
612**
613*******************************************************************************/
614void btm_ble_rand_enc_complete (UINT8 *p, UINT16 op_code, tBTM_RAND_ENC_CB *p_enc_cplt_cback)
615{
616    tBTM_RAND_ENC   params;
617    UINT8           *p_dest = params.param_buf;
618
619    BTM_TRACE_DEBUG0 ("btm_ble_rand_enc_complete");
620
621    memset(&params, 0, sizeof(tBTM_RAND_ENC));
622
623    /* If there was a callback address for vcs complete, call it */
624    if (p_enc_cplt_cback && p)
625    {
626        /* Pass paramters to the callback function */
627        STREAM_TO_UINT8(params.status, p); /* command status */
628
629        if (params.status == HCI_SUCCESS)
630        {
631            params.opcode = op_code;
632
633            if (op_code == HCI_BLE_RAND)
634                params.param_len = BT_OCTET8_LEN;
635            else
636                params.param_len = BT_OCTET16_LEN;
637
638            memcpy(p_dest, p, params.param_len);  /* Fetch return info from HCI event message */
639        }
640        if (p_enc_cplt_cback)
641            (*p_enc_cplt_cback)(&params);  /* Call the Encryption complete callback function */
642    }
643}
644
645
646#if (SMP_INCLUDED == TRUE)
647
648/*******************************************************************************
649**
650** Function         btm_ble_get_enc_key_type
651**
652** Description      This function is to increment local sign counter
653** Returns         None
654**
655*******************************************************************************/
656void btm_ble_increment_sign_ctr(BD_ADDR bd_addr, BOOLEAN is_local )
657{
658    tBTM_SEC_DEV_REC *p_dev_rec;
659
660    BTM_TRACE_DEBUG1 ("btm_ble_increment_sign_ctr is_local=%d", is_local);
661
662    if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
663    {
664        if (is_local)
665            p_dev_rec->ble.keys.local_counter++;
666        else
667            p_dev_rec->ble.keys.counter++;
668        BTM_TRACE_DEBUG3 ("is_local=%d local sign counter=%d peer sign counter=%d",
669                          is_local,
670                          p_dev_rec->ble.keys.local_counter,
671                          p_dev_rec->ble.keys.counter);
672    }
673}
674
675/*******************************************************************************
676**
677** Function         btm_ble_get_enc_key_type
678**
679** Description      This function is to get the BLE key type that has been exchanged
680**                  in betweem local device and peer device.
681**
682** Returns          p_key_type: output parameter to carry the key type value.
683**
684*******************************************************************************/
685BOOLEAN btm_ble_get_enc_key_type(BD_ADDR bd_addr, UINT8 *p_key_types)
686{
687    tBTM_SEC_DEV_REC *p_dev_rec;
688
689    BTM_TRACE_DEBUG0 ("btm_ble_get_enc_key_type");
690
691    if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
692    {
693        *p_key_types = p_dev_rec->ble.key_type;
694        return TRUE;
695    }
696    return FALSE;
697}
698
699/*******************************************************************************
700**
701** Function         btm_get_local_div
702**
703** Description      This function is called to read the local DIV
704**
705** Returns          TURE - if a valid DIV is availavle
706*******************************************************************************/
707BOOLEAN btm_get_local_div (BD_ADDR bd_addr, UINT16 *p_div)
708{
709    tBTM_SEC_DEV_REC   *p_dev_rec;
710    BOOLEAN            status = FALSE;
711    BTM_TRACE_DEBUG0 ("btm_get_local_div");
712
713    BTM_TRACE_DEBUG6("bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
714                     bd_addr[0],bd_addr[1],
715                     bd_addr[2],bd_addr[3],
716                     bd_addr[4],bd_addr[5]);
717
718    p_dev_rec = btm_find_dev (bd_addr);
719
720    if (p_dev_rec && p_dev_rec->ble.keys.div)
721    {
722        status = TRUE;
723        *p_div = p_dev_rec->ble.keys.div;
724    }
725    BTM_TRACE_DEBUG2 ("btm_get_local_div status=%d (1-OK) DIV=0x%x", status, *p_div);
726    return status;
727}
728
729/*******************************************************************************
730**
731** Function         btm_sec_save_le_key
732**
733** Description      This function is called by the SMP to update
734**                  an  BLE key.  SMP is internal, whereas all the keys shall
735**                  be sent to the application.  The function is also called
736**                  when application passes ble key stored in NVRAM to the btm_sec.
737**                  pass_to_application parameter is false in this case.
738**
739** Returns          void
740**
741*******************************************************************************/
742void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type, tBTM_LE_KEY_VALUE *p_keys,
743                         BOOLEAN pass_to_application)
744{
745    tBTM_SEC_DEV_REC *p_rec;
746    tBTM_LE_EVT_DATA    cb_data;
747
748    BTM_TRACE_DEBUG2 ("btm_sec_save_le_key key_type=0x%x pass_to_application=%d",key_type, pass_to_application);
749    /* Store the updated key in the device database */
750
751    BTM_TRACE_DEBUG6("bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
752                     bd_addr[0],bd_addr[1],
753                     bd_addr[2],bd_addr[3],
754                     bd_addr[4],bd_addr[5]);
755
756    if ((p_rec = btm_find_dev (bd_addr)) != NULL && p_keys)
757    {
758        switch (key_type)
759        {
760            case BTM_LE_KEY_PENC:
761                memcpy(p_rec->ble.keys.ltk, p_keys->penc_key.ltk, BT_OCTET16_LEN);
762                memcpy(p_rec->ble.keys.rand, p_keys->penc_key.rand, BT_OCTET8_LEN);
763                p_rec->ble.keys.sec_level = p_keys->penc_key.sec_level;
764                p_rec->ble.keys.ediv = p_keys->penc_key.ediv;
765                p_rec->ble.keys.key_size = p_keys->penc_key.key_size;
766                p_rec->ble.key_type |= BTM_LE_KEY_PENC;
767                p_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
768                if (p_keys->penc_key.sec_level == SMP_SEC_AUTHENTICATED)
769                    p_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
770                else
771                    p_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
772                BTM_TRACE_DEBUG3("BTM_LE_KEY_PENC key_type=0x%x sec_flags=0x%x sec_leve=0x%x",
773                                 p_rec->ble.key_type,
774                                 p_rec->sec_flags,
775                                 p_rec->ble.keys.sec_level);
776                break;
777
778            case BTM_LE_KEY_PID:
779                memcpy(p_rec->ble.keys.irk, p_keys->pid_key, BT_OCTET16_LEN);
780                p_rec->ble.key_type |= BTM_LE_KEY_PID;
781                BTM_TRACE_DEBUG1("BTM_LE_KEY_PID key_type=0x%x save peer IRK",  p_rec->ble.key_type);
782                break;
783
784            case BTM_LE_KEY_PCSRK:
785                memcpy(p_rec->ble.keys.csrk, p_keys->pcsrk_key.csrk, BT_OCTET16_LEN);
786                p_rec->ble.keys.srk_sec_level = p_keys->pcsrk_key.sec_level;
787                p_rec->ble.keys.counter  = p_keys->pcsrk_key.counter;
788                p_rec->ble.key_type |= BTM_LE_KEY_PCSRK;
789                p_rec->sec_flags |=  BTM_SEC_LINK_KEY_KNOWN;
790                if ( p_keys->pcsrk_key.sec_level== SMP_SEC_AUTHENTICATED)
791                    p_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
792                else
793                    p_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
794
795                BTM_TRACE_DEBUG4("BTM_LE_KEY_PCSRK key_type=0x%x sec_flags=0x%x sec_level=0x%x peer_counter=%d",
796                                 p_rec->ble.key_type,
797                                 p_rec->sec_flags,
798                                 p_rec->ble.keys.srk_sec_level,
799                                 p_rec->ble.keys.counter );
800                break;
801
802            case BTM_LE_KEY_LENC:
803                p_rec->ble.keys.div = p_keys->lenc_key.div; /* update DIV */
804                p_rec->ble.keys.sec_level = p_keys->lenc_key.sec_level;
805                p_rec->ble.keys.key_size = p_keys->lenc_key.key_size;
806                p_rec->ble.key_type |= BTM_LE_KEY_LENC;
807
808                BTM_TRACE_DEBUG4("BTM_LE_KEY_LENC key_type=0x%x DIV=0x%x key_size=0x%x sec_level=0x%x",
809                                 p_rec->ble.key_type,
810                                 p_rec->ble.keys.div,
811                                 p_rec->ble.keys.key_size,
812                                 p_rec->ble.keys.sec_level );
813                break;
814
815            case BTM_LE_KEY_LCSRK:/* local CSRK has been delivered */
816                p_rec->ble.keys.div = p_keys->lcsrk_key.div; /* update DIV */
817                p_rec->ble.keys.local_csrk_sec_level = p_keys->lcsrk_key.sec_level;
818                p_rec->ble.keys.local_counter  = p_keys->lcsrk_key.counter;
819                p_rec->ble.key_type |= BTM_LE_KEY_LCSRK;
820                BTM_TRACE_DEBUG4("BTM_LE_KEY_LCSRK key_type=0x%x DIV=0x%x scrk_sec_level=0x%x local_counter=%d",
821                                 p_rec->ble.key_type,
822                                 p_rec->ble.keys.div,
823                                 p_rec->ble.keys.local_csrk_sec_level,
824                                 p_rec->ble.keys.local_counter );
825                break;
826
827            default:
828                BTM_TRACE_WARNING1("btm_sec_save_le_key (Bad key_type 0x%02x)", key_type);
829                return;
830        }
831
832        BTM_TRACE_DEBUG3 ("BLE key type 0x%02x updated for BDA: %08x%04x (btm_sec_save_le_key)", key_type,
833                          (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
834                          (bd_addr[4]<<8)+bd_addr[5]);
835
836        /* Notify the application that one of the BLE keys has been updated
837           If link key is in progress, it will get sent later.*/
838        if (pass_to_application && btm_cb.api.p_le_callback)
839        {
840            cb_data.key.p_key_value = p_keys;
841            cb_data.key.key_type = key_type;
842
843            (*btm_cb.api.p_le_callback) (BTM_LE_KEY_EVT, bd_addr, &cb_data);
844        }
845        return;
846    }
847
848    BTM_TRACE_WARNING3 ("BLE key type 0x%02x called for Unknown BDA or type: %08x%04x !! (btm_sec_save_le_key)", key_type,
849                        (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
850                        (bd_addr[4]<<8)+bd_addr[5]);
851
852    if (p_rec)
853    {
854        BTM_TRACE_DEBUG1 ("sec_flags=0x%x", p_rec->sec_flags);
855    }
856}
857
858/*******************************************************************************
859**
860** Function         btm_ble_update_sec_key_size
861**
862** Description      update the current lin kencryption key size
863**
864** Returns          void
865**
866*******************************************************************************/
867void btm_ble_update_sec_key_size(BD_ADDR bd_addr, UINT8 enc_key_size)
868{
869    tBTM_SEC_DEV_REC *p_rec;
870
871    BTM_TRACE_DEBUG1("btm_ble_update_sec_key_size enc_key_size = %d", enc_key_size);
872
873    if ((p_rec = btm_find_dev (bd_addr)) != NULL )
874    {
875        p_rec->enc_key_size = enc_key_size;
876    }
877}
878
879/*******************************************************************************
880**
881** Function         btm_ble_read_sec_key_size
882**
883** Description      update the current lin kencryption key size
884**
885** Returns          void
886**
887*******************************************************************************/
888UINT8 btm_ble_read_sec_key_size(BD_ADDR bd_addr)
889{
890    tBTM_SEC_DEV_REC *p_rec;
891
892    if ((p_rec = btm_find_dev (bd_addr)) != NULL )
893    {
894        return p_rec->enc_key_size;
895    }
896    else
897        return 0;
898}
899
900/*******************************************************************************
901**
902** Function         btm_ble_link_sec_check
903**
904** Description      Check BLE link security level match.
905**
906** Returns          TRUE: check is OK and the *p_sec_req_act contain the action
907**
908*******************************************************************************/
909void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE_SEC_REQ_ACT *p_sec_req_act)
910{
911    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
912    UINT8 req_sec_level, cur_sec_level;
913
914    BTM_TRACE_DEBUG1 ("btm_ble_link_sec_check auth_req =0x%x", auth_req);
915
916    if (p_dev_rec == NULL)
917    {
918        BTM_TRACE_ERROR0 ("btm_ble_link_sec_check received for unknown device");
919        return;
920    }
921
922    if (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING)
923    {
924        /* race condition: discard the security request while master is encrypting the link */
925        *p_sec_req_act = BTM_BLE_SEC_REQ_ACT_DISCARD;
926    }
927    else
928    {
929        req_sec_level = BTM_LE_SEC_UNAUTHENTICATE;
930        if ((auth_req == (BTM_LE_AUTH_REQ_BOND|BTM_LE_AUTH_REQ_MITM)) ||
931            (auth_req == (BTM_LE_AUTH_REQ_MITM)) )
932        {
933            req_sec_level = BTM_LE_SEC_AUTHENTICATED;
934        }
935
936        BTM_TRACE_DEBUG1 ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags);
937
938        /* currently encrpted  */
939        if (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
940        {
941            if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED)
942                cur_sec_level = BTM_LE_SEC_AUTHENTICATED;
943            else
944                cur_sec_level = BTM_LE_SEC_UNAUTHENTICATE;
945        }
946        else /* unencrypted link */
947        {
948            /* if bonded, get the key security level */
949            if (p_dev_rec->ble.key_type & BTM_LE_KEY_PENC)
950                cur_sec_level = p_dev_rec->ble.keys.sec_level;
951            else
952                cur_sec_level = BTM_LE_SEC_NONE;
953        }
954
955        if (cur_sec_level >= req_sec_level)
956        {
957            if (cur_sec_level == BTM_LE_SEC_NONE)
958            {
959                *p_sec_req_act = BTM_BLE_SEC_REQ_ACT_NONE;
960            }
961            else
962            {
963                /* To avoid re-encryption on an encrypted link for an equal condition encryption
964                if (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
965                    *p_sec_req_act = BTM_BLE_SEC_REQ_ACT_DISCARD;
966                else
967                */
968                    *p_sec_req_act = BTM_BLE_SEC_REQ_ACT_ENCRYPT;
969            }
970        }
971        else
972        {
973            *p_sec_req_act =  BTM_BLE_SEC_REQ_ACT_PAIR; /* start the pariring process to upgrade the keys*/
974        }
975    }
976
977    BTM_TRACE_DEBUG3("cur_sec_level=%d req_sec_level=%d sec_req_act=%d",
978                     cur_sec_level,
979                     req_sec_level,
980                     *p_sec_req_act);
981
982}
983
984/*******************************************************************************
985**
986** Function         btm_ble_set_encryption
987**
988** Description      This function is called to ensure that LE connection is
989**                  encrypted.  Should be called only on an open connection.
990**                  Typically only needed for connections that first want to
991**                  bring up unencrypted links, then later encrypt them.
992**
993** Returns          void
994**                  the local device ER is copied into er
995**
996*******************************************************************************/
997tBTM_STATUS btm_ble_set_encryption (BD_ADDR bd_addr, void *p_ref_data, UINT8 link_role)
998{
999    tBTM_STATUS         cmd = BTM_NO_RESOURCES;
1000    tBTM_BLE_SEC_ACT    sec_act = *(tBTM_BLE_SEC_ACT *)p_ref_data ;
1001    tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bd_addr);
1002
1003    BTM_TRACE_DEBUG2 ("btm_ble_set_encryption sec_act=0x%x role_master=%d", sec_act, p_rec->role_master);
1004
1005    if (p_rec == NULL)
1006    {
1007        return(BTM_WRONG_MODE);
1008    }
1009
1010    if (sec_act == BTM_BLE_SEC_ENCRYPT_MITM)
1011    {
1012        p_rec->security_required |= BTM_SEC_IN_MITM;
1013    }
1014
1015    switch (sec_act)
1016    {
1017        case BTM_BLE_SEC_ENCRYPT:
1018            if (link_role == BTM_ROLE_MASTER)
1019            {
1020                /* start link layer encryption using the security info stored */
1021                btm_ble_start_encrypt(bd_addr, FALSE, NULL);
1022                p_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
1023                cmd = BTM_CMD_STARTED;
1024                break;
1025            }
1026            /* if salve role then fall through to call SMP_Pair below which will send a
1027               sec_request to request the master to encrypt the link */
1028        case BTM_BLE_SEC_ENCRYPT_NO_MITM:
1029        case BTM_BLE_SEC_ENCRYPT_MITM:
1030
1031            if (SMP_Pair(bd_addr) == SMP_STARTED)
1032            {
1033                cmd = BTM_CMD_STARTED;
1034                p_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
1035            }
1036            break;
1037
1038        default:
1039            cmd = BTM_SUCCESS;
1040            break;
1041    }
1042    return cmd;
1043}
1044
1045/*******************************************************************************
1046**
1047** Function         btm_ble_ltk_request
1048**
1049** Description      This function is called when encryption request is received
1050**                  on a slave device.
1051**
1052**
1053** Returns          void
1054**
1055*******************************************************************************/
1056void btm_ble_ltk_request(UINT16 handle, UINT8 rand[8], UINT16 ediv)
1057{
1058    tBTM_CB *p_cb = &btm_cb;
1059    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
1060    BT_OCTET8 dummy_stk = {0};
1061
1062    BTM_TRACE_DEBUG0 ("btm_ble_ltk_request");
1063
1064    p_cb->ediv = ediv;
1065
1066    memcpy(p_cb->enc_rand, rand, BT_OCTET8_LEN);
1067
1068    if (!smp_proc_ltk_request(p_dev_rec->bd_addr))
1069        btm_ble_ltk_request_reply(p_dev_rec->bd_addr, FALSE, dummy_stk);
1070
1071
1072}
1073
1074/*******************************************************************************
1075**
1076** Function         btm_ble_start_encrypt
1077**
1078** Description      This function is called to start LE encryption.
1079**
1080**
1081** Returns          void
1082**
1083*******************************************************************************/
1084BOOLEAN btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk)
1085{
1086    tBTM_CB *p_cb = &btm_cb;
1087    tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bda);
1088    BT_OCTET8    dummy_rand = {0};
1089
1090    BTM_TRACE_DEBUG0 ("btm_ble_start_encrypt");
1091
1092    if (!p_rec ||
1093        (p_rec && p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING))
1094        return FALSE;
1095
1096    if (p_rec->sec_state == BTM_SEC_STATE_IDLE)
1097        p_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
1098    p_cb->enc_handle = p_rec->hci_handle;
1099
1100    if (use_stk)
1101    {
1102        if (!btsnd_hcic_ble_start_enc(p_rec->hci_handle, dummy_rand, 0, stk))
1103            return FALSE;
1104    }
1105    else
1106    {
1107        if (!btsnd_hcic_ble_start_enc(p_rec->hci_handle, p_rec->ble.keys.rand,
1108                                      p_rec->ble.keys.ediv, p_rec->ble.keys.ltk))
1109            return FALSE;
1110    }
1111    return TRUE;
1112}
1113
1114/*******************************************************************************
1115**
1116** Function         btm_ble_link_encrypted
1117**
1118** Description      This function is called when LE link encrption status is changed.
1119**
1120** Returns          void
1121**
1122*******************************************************************************/
1123void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable)
1124{
1125    tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_dev (bd_addr);
1126
1127    BTM_TRACE_DEBUG1 ("btm_ble_link_encrypted encr_enable=%d", encr_enable);
1128
1129    smp_link_encrypted(bd_addr, encr_enable);
1130
1131    if (p_dev_rec)
1132    {
1133        BTM_TRACE_DEBUG1(" p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags);
1134
1135        if (encr_enable && p_dev_rec->enc_key_size == 0)
1136            p_dev_rec->enc_key_size = p_dev_rec->ble.keys.key_size;
1137
1138        if (p_dev_rec->p_callback)
1139        {
1140            if (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING)
1141            {
1142                if (encr_enable)
1143                    btm_sec_dev_rec_cback_event(p_dev_rec, BTM_SUCCESS);
1144                else if (p_dev_rec->role_master)
1145                    btm_sec_dev_rec_cback_event(p_dev_rec, BTM_ERR_PROCESSING);
1146            }
1147        }
1148        p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
1149    }
1150}
1151
1152/*******************************************************************************
1153** Function         btm_enc_proc_ltk
1154** Description      send LTK reply when it's ready.
1155*******************************************************************************/
1156static void btm_enc_proc_ltk(tSMP_ENC *p)
1157{
1158    UINT8   i;
1159    BTM_TRACE_DEBUG0 ("btm_enc_proc_ltk");
1160    if (p && p->param_len == BT_OCTET16_LEN)
1161    {
1162        for (i = 0; i < (BT_OCTET16_LEN - btm_cb.key_size); i ++)
1163            p->param_buf[BT_OCTET16_LEN - i - 1] = 0;
1164        btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p->param_buf);
1165    }
1166}
1167
1168/*******************************************************************************
1169** Function         btm_enc_proc_slave_y
1170** Description      calculate LTK when Y is ready
1171*******************************************************************************/
1172static void btm_enc_proc_slave_y(tSMP_ENC *p)
1173{
1174    UINT16  div, y;
1175    UINT8   *pp = p->param_buf;
1176    tBTM_CB *p_cb = &btm_cb;
1177    tSMP_ENC output;
1178    tBTM_SEC_DEV_REC *p_dev_rec;
1179
1180    BTM_TRACE_DEBUG0 ("btm_enc_proc_slave_y");
1181    if (p != NULL)
1182    {
1183        STREAM_TO_UINT16(y, pp);
1184
1185        div = p_cb->ediv ^ y;
1186        p_dev_rec = btm_find_dev_by_handle (p_cb->enc_handle);
1187
1188        if ( p_dev_rec &&
1189            p_dev_rec->ble.keys.div == div )
1190        {
1191            BTM_TRACE_DEBUG0 ("LTK request OK");
1192            /* calculating LTK , LTK = E er(div) */
1193            SMP_Encrypt(p_cb->devcb.er, BT_OCTET16_LEN, (UINT8 *)&div, 2, &output);
1194            btm_enc_proc_ltk(&output);
1195        }
1196        else
1197        {
1198            BTM_TRACE_DEBUG0 ("LTK request failed - send negative reply");
1199            btsnd_hcic_ble_ltk_req_neg_reply(p_cb->enc_handle);
1200            if (p_dev_rec)
1201                btm_ble_link_encrypted(p_dev_rec->bd_addr, 0);
1202
1203        }
1204    }
1205}
1206
1207/*******************************************************************************
1208**
1209** Function         btm_ble_ltk_request_reply
1210**
1211** Description      This function is called to send a LTK request reply on a slave
1212**                  device.
1213**
1214** Returns          void
1215**
1216*******************************************************************************/
1217void btm_ble_ltk_request_reply(BD_ADDR bda,  BOOLEAN use_stk, BT_OCTET16 stk)
1218{
1219    tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bda);
1220    tBTM_CB *p_cb = &btm_cb;
1221    tSMP_ENC output;
1222
1223    if (p_rec == NULL)
1224    {
1225        BTM_TRACE_ERROR0("btm_ble_ltk_request_reply received for unknown device");
1226        return;
1227    }
1228
1229    BTM_TRACE_DEBUG0 ("btm_ble_ltk_request_reply");
1230    p_cb->enc_handle = p_rec->hci_handle;
1231    p_cb->key_size = p_rec->ble.keys.key_size;
1232
1233    BTM_TRACE_ERROR1("key size = %d", p_rec->ble.keys.key_size);
1234    if (use_stk)
1235    {
1236        btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, stk);
1237    }
1238    else /* calculate LTK using peer device  */
1239    {
1240        /* generate Y= Encrypt(DHK, Rand) received from encrypt request  */
1241        SMP_Encrypt(p_cb->devcb.id_keys.dhk, BT_OCTET16_LEN, p_cb->enc_rand,
1242                    BT_OCTET8_LEN, &output);
1243        btm_enc_proc_slave_y(&output);
1244    }
1245}
1246
1247/*******************************************************************************
1248**
1249** Function         btm_ble_io_capabilities_req
1250**
1251** Description      This function is called to handle SMP get IO capability request.
1252**
1253** Returns          void
1254**
1255*******************************************************************************/
1256UINT8 btm_ble_io_capabilities_req(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_LE_IO_REQ *p_data)
1257{
1258    UINT8           callback_rc = BTM_SUCCESS;
1259    BTM_TRACE_DEBUG0 ("btm_ble_io_capabilities_req");
1260    if (btm_cb.api.p_le_callback)
1261    {
1262        /* the callback function implementation may change the IO capability... */
1263        callback_rc = (*btm_cb.api.p_le_callback) (BTM_LE_IO_REQ_EVT, p_dev_rec->bd_addr, (tBTM_LE_EVT_DATA *)p_data);
1264    }
1265#if BTM_OOB_INCLUDED == TRUE
1266    if ((callback_rc == BTM_SUCCESS) || (BTM_OOB_UNKNOWN != p_data->oob_data))
1267#else
1268    if (callback_rc == BTM_SUCCESS)
1269#endif
1270    {
1271        p_data->auth_req &= BTM_LE_AUTH_REQ_MASK;
1272
1273        BTM_TRACE_DEBUG2 ("btm_ble_io_capabilities_req 1: p_dev_rec->security_required = %d auth_req:%d",
1274                          p_dev_rec->security_required, p_data->auth_req);
1275        BTM_TRACE_DEBUG2 ("btm_ble_io_capabilities_req 2: i_keys=0x%x r_keys=0x%x (bit 0-LTK 1-IRK 2-CSRK)",
1276                          p_data->init_keys,
1277                          p_data->resp_keys);
1278
1279        /* if authentication requires MITM protection, put on the mask */
1280        if (p_dev_rec->security_required & BTM_SEC_IN_MITM)
1281            p_data->auth_req |= BTM_LE_AUTH_REQ_MITM;
1282
1283        if (!(p_data->auth_req & SMP_AUTH_BOND))
1284        {
1285            BTM_TRACE_DEBUG0("Non bonding: No keys should be exchanged");
1286            p_data->init_keys = 0;
1287            p_data->resp_keys = 0;
1288        }
1289
1290        BTM_TRACE_DEBUG1 ("btm_ble_io_capabilities_req 3: auth_req:%d", p_data->auth_req);
1291        BTM_TRACE_DEBUG2 ("btm_ble_io_capabilities_req 4: i_keys=0x%x r_keys=0x%x",
1292                          p_data->init_keys,
1293                          p_data->resp_keys);
1294
1295        BTM_TRACE_DEBUG2 ("btm_ble_io_capabilities_req 5: p_data->io_cap = %d auth_req:%d",
1296                          p_data->io_cap, p_data->auth_req);
1297
1298        /* remove MITM protection requirement if IO cap does not allow it */
1299        if ((p_data->io_cap == BTM_IO_CAP_NONE) && p_data->oob_data == SMP_OOB_NONE)
1300            p_data->auth_req &= ~BTM_LE_AUTH_REQ_MITM;
1301
1302        BTM_TRACE_DEBUG3 ("btm_ble_io_capabilities_req 6: IO_CAP:%d oob_data:%d auth_req:%d",
1303                          p_data->io_cap, p_data->oob_data, p_data->auth_req);
1304    }
1305    return callback_rc;
1306}
1307
1308/*****************************************************************************
1309**  Function        btm_proc_smp_cback
1310**
1311**  Description     This function is the SMP callback handler.
1312**
1313******************************************************************************/
1314UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
1315{
1316    tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_dev (bd_addr);
1317    UINT8 res;
1318
1319    BTM_TRACE_DEBUG1 ("btm_proc_smp_cback event = %d", event);
1320
1321    if (p_dev_rec != NULL)
1322    {
1323        switch (event)
1324        {
1325            case SMP_IO_CAP_REQ_EVT:
1326                btm_ble_io_capabilities_req(p_dev_rec, (tBTM_LE_IO_REQ *)&p_data->io_req);
1327                break;
1328
1329            case SMP_PASSKEY_REQ_EVT:
1330            case SMP_PASSKEY_NOTIF_EVT:
1331            case SMP_OOB_REQ_EVT:
1332                p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
1333            case SMP_SEC_REQUEST_EVT:
1334            case SMP_COMPLT_EVT:
1335                if (btm_cb.api.p_le_callback)
1336                {
1337                    /* the callback function implementation may change the IO capability... */
1338                    BTM_TRACE_DEBUG1 ("btm_cb.api.p_le_callback=0x%x", btm_cb.api.p_le_callback );
1339                    (*btm_cb.api.p_le_callback) (event, bd_addr, (tBTM_LE_EVT_DATA *)p_data);
1340                }
1341                else
1342                {
1343                    BTM_TRACE_ERROR0 ("btm_proc_smp_cback: btm_cb.api.p_le_callback ==NULL");
1344                }
1345
1346                if (event == SMP_COMPLT_EVT)
1347                {
1348                    BTM_TRACE_DEBUG2 ("evt=SMP_COMPLT_EVT before update sec_level=0x%x sec_flags=0x%x", p_data->cmplt.sec_level , p_dev_rec->sec_flags );
1349
1350                    res = (p_data->cmplt.reason == SMP_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING;
1351
1352                    BTM_TRACE_DEBUG3 ("after update result=%d sec_level=0x%x sec_flags=0x%x",
1353                                      res, p_data->cmplt.sec_level , p_dev_rec->sec_flags );
1354
1355                    btm_sec_dev_rec_cback_event(p_dev_rec, res);
1356
1357                    if (p_data->cmplt.is_pair_cancel && btm_cb.api.p_bond_cancel_cmpl_callback )
1358                    {
1359                        BTM_TRACE_DEBUG0 ("Pairing Cancel completed");
1360                        (*btm_cb.api.p_bond_cancel_cmpl_callback)(BTM_SUCCESS);
1361                    }
1362#if BTM_BLE_CONFORMANCE_TESTING == TRUE
1363                    if (res != BTM_SUCCESS)
1364                    {
1365                        if (!btm_cb.devcb.no_disc_if_pair_fail)
1366                        {
1367                            BTM_TRACE_DEBUG0 ("Pairing failed - Remove ACL");
1368                            btm_remove_acl(bd_addr);
1369                        }
1370                        else
1371                        {
1372                            BTM_TRACE_DEBUG0 ("Pairing failed - Not Removing ACL");
1373	                        p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
1374                        }
1375                    }
1376#else
1377                    if (res != BTM_SUCCESS)
1378                        btm_remove_acl(bd_addr);
1379#endif
1380
1381                    BTM_TRACE_DEBUG3 ("btm_cb pairing_state=%x pairing_flags=%x pin_code_len=%x",
1382                                      btm_cb.pairing_state,
1383                                      btm_cb.pairing_flags,
1384                                      btm_cb.pin_code_len  );
1385                    BTM_TRACE_DEBUG6 ("btm_cb.pairing_bda %02x:%02x:%02x:%02x:%02x:%02x",
1386                                      btm_cb.pairing_bda[0], btm_cb.pairing_bda[1], btm_cb.pairing_bda[2],
1387                                      btm_cb.pairing_bda[3], btm_cb.pairing_bda[4], btm_cb.pairing_bda[5]);
1388
1389                    memset (btm_cb.pairing_bda, 0xff, BD_ADDR_LEN);
1390                    btm_cb.pairing_flags = 0;
1391                }
1392                break;
1393
1394            default:
1395                BTM_TRACE_DEBUG1 ("unknown event = %d", event);
1396                break;
1397
1398
1399        }
1400    }
1401    else
1402    {
1403        BTM_TRACE_ERROR0("btm_proc_smp_cback received for unknown device");
1404    }
1405
1406    return 0;
1407}
1408
1409#endif  /* SMP_INCLUDED */
1410#endif  /* BLE_INCLUDED */
1411
1412
1413/*******************************************************************************
1414**
1415** Function         BTM_BleDataSignature
1416**
1417** Description      This function is called to sign the data using AES128 CMAC
1418**                  algorith.
1419**
1420** Parameter        bd_addr: target device the data to be signed for.
1421**                  p_text: singing data
1422**                  len: length of the data to be signed.
1423**                  signature: output parameter where data signature is going to
1424**                             be stored.
1425**
1426** Returns          TRUE if signing sucessul, otherwise FALSE.
1427**
1428*******************************************************************************/
1429BOOLEAN BTM_BleDataSignature (BD_ADDR bd_addr, UINT8 *p_text, UINT16 len,
1430                              BLE_SIGNATURE signature)
1431{
1432    BOOLEAN     ret = FALSE;
1433#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
1434    tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bd_addr);
1435    UINT8   *p_buf, *pp;
1436
1437    BT_OCTET16  er;
1438    UINT16      div;
1439    UINT8       temp[4]; /* for (r || DIV)  r=1*/
1440    UINT16      r=1;
1441    UINT8       *p=temp, *p_mac = (UINT8 *)signature;
1442    tSMP_ENC    output;
1443    BT_OCTET16  local_csrk;
1444
1445    BTM_TRACE_DEBUG0 ("BTM_BleDataSignature");
1446    if (p_rec == NULL)
1447    {
1448        BTM_TRACE_ERROR0("data signing can not be done from unknow device");
1449    }
1450    else
1451    {
1452        if ((p_buf = (UINT8 *)GKI_getbuf((UINT16)(len + 4))) != NULL)
1453        {
1454            BTM_TRACE_DEBUG0("Start to generate Local CSRK");
1455            /* prepare plain text */
1456            if (p_text)
1457            {
1458                memcpy(p_buf, p_text, len);
1459                pp = (p_buf + len);
1460            }
1461
1462#if BTM_BLE_CONFORMANCE_TESTING == TRUE
1463            if ( btm_cb.devcb.enable_test_local_sign_cntr)
1464            {
1465                BTM_TRACE_DEBUG1 ("Use Test local counter value from script counter_val=%d", btm_cb.devcb.test_local_sign_cntr);
1466                UINT32_TO_STREAM(pp, btm_cb.devcb.test_local_sign_cntr);
1467            }
1468            else
1469            {
1470                UINT32_TO_STREAM(pp, p_rec->ble.keys.local_counter);
1471            }
1472#else
1473            UINT32_TO_STREAM(pp, p_rec->ble.keys.local_counter);
1474#endif
1475            /* compute local csrk */
1476            if (btm_get_local_div(bd_addr, &div))
1477            {
1478                BTM_TRACE_DEBUG1 ("compute_csrk div=%x", div);
1479                BTM_GetDeviceEncRoot(er);
1480
1481                /* CSRK = d1(ER, DIV, 1) */
1482                UINT16_TO_STREAM(p, div);
1483                UINT16_TO_STREAM(p, r);
1484
1485                if (!SMP_Encrypt(er, BT_OCTET16_LEN, temp, 4, &output))
1486                {
1487                    BTM_TRACE_ERROR0("Local CSRK generation failed ");
1488                }
1489                else
1490                {
1491                    BTM_TRACE_DEBUG0("local CSRK generation success");
1492                    memcpy((void *)local_csrk, output.param_buf, BT_OCTET16_LEN);
1493
1494
1495#if BTM_BLE_CONFORMANCE_TESTING == TRUE
1496                    if (btm_cb.devcb.enable_test_local_sign_cntr)
1497                    {
1498                        UINT32_TO_STREAM(p_mac, btm_cb.devcb.test_local_sign_cntr);
1499                    }
1500                    else
1501                    {
1502                        UINT32_TO_STREAM(p_mac, p_rec->ble.keys.local_counter);
1503                    }
1504#else
1505                    UINT32_TO_STREAM(p_mac, p_rec->ble.keys.local_counter);
1506#endif
1507
1508                    if ((ret = AES_CMAC(local_csrk, p_buf, (UINT16)(len + 4), BTM_CMAC_TLEN_SIZE, p_mac)) == TRUE)
1509                    {
1510                        btm_ble_increment_sign_ctr(bd_addr, TRUE);
1511
1512#if BTM_BLE_CONFORMANCE_TESTING == TRUE
1513                        if ( btm_cb.devcb.enable_test_mac_val)
1514                        {
1515                            BTM_TRACE_DEBUG0 ("Use MAC value from script");
1516                            memcpy(p_mac, btm_cb.devcb.test_mac, BTM_CMAC_TLEN_SIZE);
1517                        }
1518#endif
1519                    }
1520                    BTM_TRACE_DEBUG1("BTM_BleDataSignature p_mac = %d", p_mac);
1521                    BTM_TRACE_DEBUG4("p_mac[0] = 0x%02x p_mac[1] = 0x%02x p_mac[2] = 0x%02x p_mac[3] = 0x%02x",
1522                                     *p_mac, *(p_mac + 1), *(p_mac + 2), *(p_mac + 3));
1523                    BTM_TRACE_DEBUG4("p_mac[4] = 0x%02x p_mac[5] = 0x%02x p_mac[6] = 0x%02x p_mac[7] = 0x%02x",
1524                                     *(p_mac + 4), *(p_mac + 5), *(p_mac + 6), *(p_mac + 7));
1525
1526                    GKI_freebuf(p_buf);
1527                }
1528            }
1529        }
1530    }
1531#endif  /* BLE_INCLUDED */
1532    return ret;
1533}
1534
1535/*******************************************************************************
1536**
1537** Function         BTM_BleVerifySignature
1538**
1539** Description      This function is called to verify the data signature
1540**
1541** Parameter        bd_addr: target device the data to be signed for.
1542**                  p_orig:  original data before signature.
1543**                  len: length of the signing data
1544**                  counter: counter used when doing data signing
1545**                  p_comp: signature to be compared against.
1546
1547** Returns          TRUE if signature verified correctly; otherwise FALSE.
1548**
1549*******************************************************************************/
1550BOOLEAN BTM_BleVerifySignature (BD_ADDR bd_addr, UINT8 *p_orig, UINT16 len, UINT32 counter,
1551                             UINT8 *p_comp)
1552{
1553    BOOLEAN             verified = FALSE;
1554#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
1555    tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bd_addr);
1556    UINT8               p_mac[BTM_CMAC_TLEN_SIZE];
1557
1558    if (p_rec == NULL || (p_rec && !(p_rec->ble.key_type & BTM_LE_KEY_PCSRK)))
1559    {
1560        BTM_TRACE_ERROR0("can not verify signature for unknown device");
1561    }
1562    else if (counter < p_rec->ble.keys.counter)
1563    {
1564        BTM_TRACE_ERROR0("signature received with out dated sign counter");
1565    }
1566    else if (p_orig == NULL)
1567    {
1568        BTM_TRACE_ERROR0("No signature to verify");
1569    }
1570    else
1571    {
1572        BTM_TRACE_DEBUG2 ("BTM_BleVerifySignature rcv_cnt=%d >= expected_cnt=%d", counter, p_rec->ble.keys.counter);
1573
1574        if (AES_CMAC(p_rec->ble.keys.csrk, p_orig, len, BTM_CMAC_TLEN_SIZE, p_mac))
1575        {
1576            if (memcmp(p_mac, p_comp, BTM_CMAC_TLEN_SIZE) == 0)
1577            {
1578                btm_ble_increment_sign_ctr(bd_addr, FALSE);
1579                verified = TRUE;
1580            }
1581        }
1582    }
1583#endif  /* BLE_INCLUDED */
1584    return verified;
1585}
1586
1587#if BLE_INCLUDED == TRUE
1588/*******************************************************************************
1589**  Utility functions for LE device IR/ER generation
1590*******************************************************************************/
1591/*******************************************************************************
1592**
1593** Function         btm_notify_new_key
1594**
1595** Description      This function is to notify application new keys have been
1596**                  generated.
1597**
1598** Returns          void
1599**
1600*******************************************************************************/
1601static void btm_notify_new_key(UINT8 key_type)
1602{
1603    tBTM_BLE_LOCAL_KEYS *p_locak_keys = NULL;
1604
1605    BTM_TRACE_DEBUG1 ("btm_notify_new_key key_type=%d", key_type);
1606
1607    if (btm_cb.api.p_le_key_callback)
1608    {
1609        switch (key_type)
1610        {
1611            case BTM_BLE_KEY_TYPE_ID:
1612                BTM_TRACE_DEBUG0 ("BTM_BLE_KEY_TYPE_ID");
1613                p_locak_keys = (tBTM_BLE_LOCAL_KEYS *)&btm_cb.devcb.id_keys;
1614                break;
1615
1616            case BTM_BLE_KEY_TYPE_ER:
1617                BTM_TRACE_DEBUG0 ("BTM_BLE_KEY_TYPE_ER");
1618                p_locak_keys = (tBTM_BLE_LOCAL_KEYS *)&btm_cb.devcb.er;
1619                break;
1620
1621            default:
1622                BTM_TRACE_ERROR1("unknown key type: %d", key_type);
1623                break;
1624        }
1625        if (p_locak_keys != NULL)
1626            (*btm_cb.api.p_le_key_callback) (key_type, p_locak_keys);
1627    }
1628}
1629
1630/*******************************************************************************
1631**
1632** Function         btm_ble_process_er2
1633**
1634** Description      This function is called when ER is generated, store it in
1635**                  local control block.
1636**
1637** Returns          void
1638**
1639*******************************************************************************/
1640static void btm_ble_process_er2(tBTM_RAND_ENC *p)
1641{
1642    BTM_TRACE_DEBUG0 ("btm_ble_process_er2");
1643
1644    if (p &&p->opcode == HCI_BLE_RAND)
1645    {
1646        memcpy(&btm_cb.devcb.er[8], p->param_buf, BT_OCTET8_LEN);
1647        btm_notify_new_key(BTM_BLE_KEY_TYPE_ER);
1648    }
1649    else
1650    {
1651        BTM_TRACE_ERROR0("Generating ER2 exception.");
1652        memset(&btm_cb.devcb.er, 0, sizeof(BT_OCTET16));
1653    }
1654}
1655
1656/*******************************************************************************
1657**
1658** Function         btm_ble_process_er
1659**
1660** Description      This function is called when ER is generated, store it in
1661**                  local control block.
1662**
1663** Returns          void
1664**
1665*******************************************************************************/
1666static void btm_ble_process_er(tBTM_RAND_ENC *p)
1667{
1668    BTM_TRACE_DEBUG0 ("btm_ble_process_er");
1669
1670    if (p &&p->opcode == HCI_BLE_RAND)
1671    {
1672        memcpy(&btm_cb.devcb.er[0], p->param_buf, BT_OCTET8_LEN);
1673
1674        if (!btsnd_hcic_ble_rand((void *)btm_ble_process_er2))
1675        {
1676            memset(&btm_cb.devcb.er, 0, sizeof(BT_OCTET16));
1677            BTM_TRACE_ERROR0("Generating ER2 failed.");
1678        }
1679    }
1680    else
1681    {
1682        BTM_TRACE_ERROR0("Generating ER1 exception.");
1683    }
1684}
1685
1686/*******************************************************************************
1687**
1688** Function         btm_ble_process_irk
1689**
1690** Description      This function is called when IRK is generated, store it in
1691**                  local control block.
1692**
1693** Returns          void
1694**
1695*******************************************************************************/
1696static void btm_ble_process_irk(tSMP_ENC *p)
1697{
1698    BTM_TRACE_DEBUG0 ("btm_ble_process_irk");
1699    if (p &&p->opcode == HCI_BLE_ENCRYPT)
1700    {
1701        memcpy(btm_cb.devcb.id_keys.irk, p->param_buf, BT_OCTET16_LEN);
1702        btm_notify_new_key(BTM_BLE_KEY_TYPE_ID);
1703    }
1704    else
1705    {
1706        BTM_TRACE_ERROR0("Generating IRK exception.");
1707    }
1708
1709    /* proceed generate ER */
1710    if (!btsnd_hcic_ble_rand((void *)btm_ble_process_er))
1711    {
1712        BTM_TRACE_ERROR0("Generating ER failed.");
1713    }
1714}
1715
1716/*******************************************************************************
1717**
1718** Function         btm_ble_process_dhk
1719**
1720** Description      This function is called when DHK is calculated, store it in
1721**                  local control block, and proceed to generate ER, a 128-bits
1722**                  random number.
1723**
1724** Returns          void
1725**
1726*******************************************************************************/
1727static void btm_ble_process_dhk(tSMP_ENC *p)
1728{
1729#if SMP_INCLUDED == TRUE
1730    UINT8 btm_ble_irk_pt = 0x01;
1731    tSMP_ENC output;
1732
1733    BTM_TRACE_DEBUG0 ("btm_ble_process_dhk");
1734
1735    if (p && p->opcode == HCI_BLE_ENCRYPT)
1736    {
1737        memcpy(btm_cb.devcb.id_keys.dhk, p->param_buf, BT_OCTET16_LEN);
1738        BTM_TRACE_DEBUG0("BLE DHK generated.");
1739
1740        /* IRK = D1(IR, 1) */
1741        if (!SMP_Encrypt(btm_cb.devcb.id_keys.ir, BT_OCTET16_LEN, &btm_ble_irk_pt,
1742                         1,   &output))
1743        {
1744            /* reset all identity root related key */
1745            memset(&btm_cb.devcb.id_keys, 0, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
1746        }
1747        else
1748        {
1749            btm_ble_process_irk(&output);
1750        }
1751    }
1752    else
1753    {
1754        /* reset all identity root related key */
1755        memset(&btm_cb.devcb.id_keys, 0, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
1756    }
1757#endif
1758}
1759
1760/*******************************************************************************
1761**
1762** Function         btm_ble_process_ir2
1763**
1764** Description      This function is called when IR is generated, proceed to calculate
1765**                  DHK = Eir({0x03, 0, 0 ...})
1766**
1767**
1768** Returns          void
1769**
1770*******************************************************************************/
1771static void btm_ble_process_ir2(tBTM_RAND_ENC *p)
1772{
1773#if SMP_INCLUDED == TRUE
1774    UINT8 btm_ble_dhk_pt = 0x03;
1775    tSMP_ENC output;
1776
1777    BTM_TRACE_DEBUG0 ("btm_ble_process_ir2");
1778
1779    if (p && p->opcode == HCI_BLE_RAND)
1780    {
1781        /* remembering in control block */
1782        memcpy(&btm_cb.devcb.id_keys.ir[8], p->param_buf, BT_OCTET8_LEN);
1783        /* generate DHK= Eir({0x03, 0x00, 0x00 ...}) */
1784
1785
1786        SMP_Encrypt(btm_cb.devcb.id_keys.ir, BT_OCTET16_LEN, &btm_ble_dhk_pt,
1787                    1, &output);
1788        btm_ble_process_dhk(&output);
1789
1790        BTM_TRACE_DEBUG0("BLE IR generated.");
1791    }
1792    else
1793    {
1794        memset(&btm_cb.devcb.id_keys, 0, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
1795    }
1796#endif
1797}
1798
1799/*******************************************************************************
1800**
1801** Function         btm_ble_process_ir
1802**
1803** Description      This function is called when IR is generated, proceed to calculate
1804**                  DHK = Eir({0x02, 0, 0 ...})
1805**
1806**
1807** Returns          void
1808**
1809*******************************************************************************/
1810static void btm_ble_process_ir(tBTM_RAND_ENC *p)
1811{
1812    BTM_TRACE_DEBUG0 ("btm_ble_process_ir");
1813
1814    if (p && p->opcode == HCI_BLE_RAND)
1815    {
1816        /* remembering in control block */
1817        memcpy(btm_cb.devcb.id_keys.ir, p->param_buf, BT_OCTET8_LEN);
1818
1819        if (!btsnd_hcic_ble_rand((void *)btm_ble_process_ir2))
1820        {
1821            BTM_TRACE_ERROR0("Generating IR2 failed.");
1822            memset(&btm_cb.devcb.id_keys, 0, sizeof(tBTM_BLE_LOCAL_ID_KEYS));
1823        }
1824    }
1825}
1826
1827/*******************************************************************************
1828**
1829** Function         btm_ble_reset_id
1830**
1831** Description      This function is called to reset LE device identity.
1832**
1833** Returns          void
1834**
1835*******************************************************************************/
1836void btm_ble_reset_id( void )
1837{
1838    BTM_TRACE_DEBUG0 ("btm_ble_reset_id");
1839
1840    /* regenrate Identity Root*/
1841    if (!btsnd_hcic_ble_rand((void *)btm_ble_process_ir))
1842    {
1843        BTM_TRACE_DEBUG0("Generating IR failed.");
1844    }
1845}
1846
1847#if BTM_BLE_CONFORMANCE_TESTING == TRUE
1848/*******************************************************************************
1849**
1850** Function         btm_ble_set_no_disc_if_pair_fail
1851**
1852** Description      This function indicates that whether no disconnect of the ACL
1853**                  should be used if pairing failed
1854**
1855** Returns          void
1856**
1857*******************************************************************************/
1858void btm_ble_set_no_disc_if_pair_fail(BOOLEAN disable_disc )
1859{
1860    BTM_TRACE_DEBUG1 ("btm_ble_set_disc_enable_if_pair_fail disable_disc=%d", disable_disc);
1861    btm_cb.devcb.no_disc_if_pair_fail = disable_disc;
1862}
1863
1864/*******************************************************************************
1865**
1866** Function         btm_ble_set_test_mac_value
1867**
1868** Description      This function set test MAC value
1869**
1870** Returns          void
1871**
1872*******************************************************************************/
1873void btm_ble_set_test_mac_value(BOOLEAN enable, UINT8 *p_test_mac_val )
1874{
1875    BTM_TRACE_DEBUG1 ("btm_ble_set_test_mac_value enable=%d", enable);
1876    btm_cb.devcb.enable_test_mac_val = enable;
1877    memcpy(btm_cb.devcb.test_mac, p_test_mac_val, BT_OCTET8_LEN);
1878}
1879
1880/*******************************************************************************
1881**
1882** Function         btm_ble_set_test_local_sign_cntr_value
1883**
1884** Description      This function set test local sign counter value
1885**
1886** Returns          void
1887**
1888*******************************************************************************/
1889void btm_ble_set_test_local_sign_cntr_value(BOOLEAN enable, UINT32 test_local_sign_cntr )
1890{
1891    BTM_TRACE_DEBUG2 ("btm_ble_set_test_local_sign_cntr_value enable=%d local_sign_cntr=%d",
1892                      enable, test_local_sign_cntr);
1893    btm_cb.devcb.enable_test_local_sign_cntr = enable;
1894    btm_cb.devcb.test_local_sign_cntr =  test_local_sign_cntr;
1895}
1896
1897#endif /* BTM_BLE_CONFORMANCE_TESTING */
1898
1899
1900#endif /* BLE_INCLUDED */
1901