15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 1999-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  this file contains GATT authentication handling functions
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
255cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BLE_INCLUDED == TRUE
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
29258c2538e3b62a8cdb403f2730c45d721e5292b4Pavlin Radoslavov#include "bt_common.h"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_int.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_api.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btm_int.h"
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_sign_data
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function sign the data for write command.
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if encrypted, otherwise FALSE.
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN gatt_sign_data (tGATT_CLCB *p_clcb)
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_VALUE         *p_attr = (tGATT_VALUE *)p_clcb->p_attr_buf;
475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8               *p_data = NULL, *p;
485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16              payload_size = p_clcb->p_tcb->payload_size;
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN             status = FALSE;
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8                *p_signature;
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
52ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    /* do not need to mark channel securoty activity for data signing */
53ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    gatt_set_sec_act(p_clcb->p_tcb, GATT_SEC_OK);
54ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
55abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov    p_data = (UINT8 *)osi_malloc(p_attr->len + 3); /* 3 = 2 byte handle + opcode */
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
575fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p = p_data;
585fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    UINT8_TO_STREAM(p, GATT_SIGN_CMD_WRITE);
595fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    UINT16_TO_STREAM(p, p_attr->handle);
605fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    ARRAY_TO_STREAM(p, p_attr->value, p_attr->len);
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
625fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    /* sign data length should be attribulte value length plus 2B handle + 1B op code */
635fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    if ((payload_size - GATT_AUTH_SIGN_LEN - 3) < p_attr->len)
645fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_attr->len = payload_size - GATT_AUTH_SIGN_LEN - 3;
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
665fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    p_signature = p_attr->value + p_attr->len;
675fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    if (BTM_BleDataSignature(p_clcb->p_tcb->peer_bda,
685fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov                             p_data,
695fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov                             (UINT16)(p_attr->len + 3), /* 3 = 2 byte handle + opcode */
705fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov                             p_signature)) {
715fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        p_attr->len += BTM_BLE_AUTH_SIGN_LEN;
725fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        gatt_set_ch_state(p_clcb->p_tcb, GATT_CH_OPEN);
735fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        gatt_act_write(p_clcb, GATT_SEC_SIGN_DATA);
745fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    } else {
755fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov        gatt_end_operation(p_clcb, GATT_INTERNAL_ERROR, NULL);
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
785fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov    osi_free(p_data);
795fe6f0cf6b223e3ed6be4912d55b3ed5b41ce0cdPavlin Radoslavov
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_verify_signature
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function start to verify the sign data when receiving
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the data from peer device.
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid gatt_verify_signature(tGATT_TCB *p_tcb, BT_HDR *p_buf)
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16  cmd_len;
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   op_code;
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8   *p, *p_orig = (UINT8 *)(p_buf + 1) + p_buf->offset;
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT32  counter;
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
100b335ee9496e671bf0ef0ab28a5990c9a024ac06bAjay Panicker    if (p_buf->len < GATT_AUTH_SIGN_LEN + 4) {
101b335ee9496e671bf0ef0ab28a5990c9a024ac06bAjay Panicker        GATT_TRACE_ERROR("%s: Data length %u less than expected %u",
102b335ee9496e671bf0ef0ab28a5990c9a024ac06bAjay Panicker                         __func__, p_buf->len, GATT_AUTH_SIGN_LEN + 4);
103b335ee9496e671bf0ef0ab28a5990c9a024ac06bAjay Panicker        return;
104b335ee9496e671bf0ef0ab28a5990c9a024ac06bAjay Panicker    }
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cmd_len = p_buf->len - GATT_AUTH_SIGN_LEN + 4;
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    p =  p_orig + cmd_len - 4;
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    STREAM_TO_UINT32(counter, p);
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (BTM_BleVerifySignature(p_tcb->peer_bda, p_orig, cmd_len, counter, p))
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        STREAM_TO_UINT8(op_code, p_orig);
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gatt_server_handle_client_req (p_tcb, op_code, (UINT16)(p_buf->len - 1), p_orig);
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1168fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        /* if this is a bad signature, assume from attacker, ignore it  */
117b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR("Signature Verification Failed, data ignored");
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return;
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_sec_check_complete
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      security check complete and proceed to data sending action.
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
131ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battavoid gatt_sec_check_complete(BOOLEAN sec_check_ok, tGATT_CLCB   *p_clcb, UINT8 sec_act)
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1331a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    if (p_clcb && p_clcb->p_tcb &&
1341a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        fixed_queue_is_empty(p_clcb->p_tcb->pending_enc_clcb)) {
135ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        gatt_set_sec_act(p_clcb->p_tcb, GATT_SEC_NONE);
1361a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov    }
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!sec_check_ok)
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gatt_end_operation(p_clcb, GATT_AUTH_FAIL, NULL);
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_clcb->operation == GATTC_OPTYPE_WRITE)
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
144ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        gatt_act_write(p_clcb, sec_act);
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else if (p_clcb->operation == GATTC_OPTYPE_READ)
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gatt_act_read(p_clcb, p_clcb->counter);
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_enc_cmpl_cback
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      link encryption complete callback.
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1608fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Battavoid gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_TCB   *p_tcb;
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       sec_flag;
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     status = FALSE;
1655cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(p_ref_data);
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
167b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
1688fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL)
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
170ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING)
171ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            return;
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1731a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        tGATT_PENDING_ENC_CLCB *p_buf =
1741a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            (tGATT_PENDING_ENC_CLCB *)fixed_queue_try_dequeue(p_tcb->pending_enc_clcb);
1751a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov        if (p_buf != NULL)
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
177ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            if (result == BTM_SUCCESS)
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
179ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM )
180ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
1818fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                    BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);
1828fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
1838fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta                    if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
184ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    {
185ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                        status = TRUE;
186ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    }
187ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
188ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                else
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = TRUE;
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
1931a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            gatt_sec_check_complete(status, p_buf->p_clcb, p_tcb->sec_act);
194abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov            osi_free(p_buf);
195ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            /* start all other pending operation in queue */
1961a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            for (size_t count = fixed_queue_length(p_tcb->pending_enc_clcb);
1971a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                 count > 0; count--)
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
1991a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                p_buf = (tGATT_PENDING_ENC_CLCB *)fixed_queue_try_dequeue(p_tcb->pending_enc_clcb);
2001a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                if (p_buf != NULL)
201ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
202ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    gatt_security_check_start(p_buf->p_clcb);
203abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                    osi_free(p_buf);
204ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
205ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                else
206ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    break;
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
209ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        else
210ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
211b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            GATT_TRACE_ERROR("Unknown operation encryption completed");
212ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
216b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_ERROR("enc callback for unknown bd_addr");
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
222ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Function         gatt_notify_enc_cmpl
223ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta**
224ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Description      link encryption complete notification for all encryption process
225ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta**                  initiated outside GATT.
226ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta**
227ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta** Returns
228ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta**
229ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta*******************************************************************************/
230ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Battavoid gatt_notify_enc_cmpl(BD_ADDR bd_addr)
231ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta{
232ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tGATT_TCB   *p_tcb;
2337051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu    UINT8        i = 0;
234ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
2358fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE)) != NULL)
236ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
2377051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu        for (i = 0; i < GATT_MAX_APPS; i++)
2387051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu        {
2397051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu            if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)
2407051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu            {
2417051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu                (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if, bd_addr);
2427051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu            }
2437051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu        }
2447051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu
245ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING)
246ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        {
247ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
248ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
2491a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            size_t count = fixed_queue_length(p_tcb->pending_enc_clcb);
2501a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov            for (; count > 0; count--)
251ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            {
2521a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                tGATT_PENDING_ENC_CLCB *p_buf =
2531a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                    (tGATT_PENDING_ENC_CLCB *)fixed_queue_try_dequeue(p_tcb->pending_enc_clcb);
2541a3844f933bd63c8a381371dabfb35c6a0249e3ePavlin Radoslavov                if (p_buf != NULL)
255ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                {
256ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    gatt_security_check_start(p_buf->p_clcb);
257abd70abb5e42c9431df94fe9d2c4a78a0d8d9af9Pavlin Radoslavov                    osi_free(p_buf);
258ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                }
259ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                else
260ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                    break;
261ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            }
262ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        }
263ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
264ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    else
265ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
266b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati        GATT_TRACE_DEBUG("notify GATT for encryption completion of unknown device");
267ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    }
268ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    return;
269ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta}
270ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta/*******************************************************************************
271ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta**
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_set_sec_act
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function set the sec_act in clcb
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          none
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act)
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_tcb)
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p_tcb->sec_act = sec_act;
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_get_sec_act
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function get the sec_act in clcb
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          none
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB *p_tcb)
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_SEC_ACTION sec_act = GATT_SEC_NONE;
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (p_tcb)
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        sec_act = p_tcb->sec_act;
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return sec_act;
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_determine_sec_act
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This routine determine the security action based on auth_request and
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  current link status
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          tGATT_SEC_ACTION security action
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb )
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_SEC_ACTION    act = GATT_SEC_OK;
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8               sec_flag;
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_TCB           *p_tcb = p_clcb->p_tcb;
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_AUTH_REQ      auth_req = p_clcb->auth_req;
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN             is_link_encrypted= FALSE;
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN             is_link_key_known=FALSE;
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN             is_key_mitm=FALSE;
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8               key_type;
324ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tBTM_BLE_SEC_REQ_ACT    sec_act = BTM_LE_SEC_NONE;
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (auth_req == GATT_AUTH_REQ_NONE )
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return act;
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3298fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_clcb->p_tcb->transport);
3308fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
331ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    btm_ble_link_sec_check(p_tcb->peer_bda, auth_req, &sec_act);
332ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
333ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    /* if a encryption is pending, need to wait */
334ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if (sec_act == BTM_BLE_SEC_REQ_ACT_DISCARD &&
335ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        auth_req != GATT_AUTH_REQ_NONE)
336ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        return GATT_SEC_ENC_PENDING;
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3388fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    if (sec_flag & (BTM_SEC_FLAG_ENCRYPTED| BTM_SEC_FLAG_LKEY_KNOWN))
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3408fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (sec_flag & BTM_SEC_FLAG_ENCRYPTED)
3418fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta            is_link_encrypted = TRUE;
342ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        is_link_key_known = TRUE;
3448fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            is_key_mitm = TRUE;
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* first check link key upgrade required or not */
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (auth_req)
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATT_AUTH_REQ_MITM:
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATT_AUTH_REQ_SIGNED_MITM:
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (!is_key_mitm)
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                act = GATT_SEC_ENCRYPT_MITM;
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATT_AUTH_REQ_NO_MITM:
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATT_AUTH_REQ_SIGNED_NO_MITM:
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (!is_link_key_known)
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                act = GATT_SEC_ENCRYPT_NO_MITM;
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* now check link needs to be encrypted or not if the link key upgrade is not required */
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (act == GATT_SEC_OK)
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3708fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta        if (p_tcb->transport == BT_TRANSPORT_LE &&
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (p_clcb->operation == GATTC_OPTYPE_WRITE) &&
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            (p_clcb->op_subtype == GATT_WRITE_NO_RSP))
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            /* this is a write command request
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project               check data signing required or not */
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (!is_link_encrypted)
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                btm_ble_get_enc_key_type(p_tcb->peer_bda, &key_type);
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( (key_type & BTM_LE_KEY_LCSRK) &&
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                     ((auth_req == GATT_AUTH_REQ_SIGNED_NO_MITM) ||
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                      (auth_req == GATT_AUTH_REQ_SIGNED_MITM)))
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    act = GATT_SEC_SIGN_DATA;
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    act = GATT_SEC_ENCRYPT;
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        else
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if (!is_link_encrypted)
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                act = GATT_SEC_ENCRYPT;
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return  act ;
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_get_link_encrypt_status
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This routine get the encryption status of the specified link
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          tGATT_STATUS link encryption status
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB *p_tcb)
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS    encrypt_status = GATT_NOT_ENCRYPTED;
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8           sec_flag=0;
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4238fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta    BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_tcb->transport);
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if ((sec_flag & BTM_SEC_FLAG_ENCRYPTED) && (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN))
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        encrypt_status = GATT_ENCRYPED_NO_MITM;
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            encrypt_status = GATT_ENCRYPED_MITM;
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
432b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG("gatt_get_link_encrypt_status status=0x%x",encrypt_status);
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return  encrypt_status ;
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function          gatt_convert_sec_action
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Convert GATT security action enum into equivalent BTM BLE security action enum
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          BOOLEAN TRUE - conversation is successful
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic BOOLEAN gatt_convert_sec_action(tGATT_SEC_ACTION gatt_sec_act, tBTM_BLE_SEC_ACT *p_btm_sec_act )
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN status = TRUE;
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (gatt_sec_act)
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATT_SEC_ENCRYPT:
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_btm_sec_act = BTM_BLE_SEC_ENCRYPT;
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATT_SEC_ENCRYPT_NO_MITM:
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_btm_sec_act = BTM_BLE_SEC_ENCRYPT_NO_MITM;
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATT_SEC_ENCRYPT_MITM:
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *p_btm_sec_act = BTM_BLE_SEC_ENCRYPT_MITM;
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = FALSE;
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_check_enc_req
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      check link security.
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          TRUE if encrypted, otherwise FALSE.
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectBOOLEAN gatt_security_check_start(tGATT_CLCB *p_clcb)
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_TCB           *p_tcb = p_clcb->p_tcb;
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_SEC_ACTION    gatt_sec_act;
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_BLE_SEC_ACT    btm_ble_sec_act;
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN             status = TRUE;
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBTM_STATUS         btm_status;
483ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    tGATT_SEC_ACTION    sec_act_old =  gatt_get_sec_act(p_tcb);
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
485ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    gatt_sec_act = gatt_determine_sec_act(p_clcb);
486ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
487ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if (sec_act_old == GATT_SEC_NONE)
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        gatt_set_sec_act(p_tcb, gatt_sec_act);
489ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
490ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    switch (gatt_sec_act )
491ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    {
492ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        case GATT_SEC_SIGN_DATA:
493b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            GATT_TRACE_DEBUG("gatt_security_check_start: Do data signing");
494ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            gatt_sign_data(p_clcb);
495ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            break;
496ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        case GATT_SEC_ENCRYPT:
497ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        case GATT_SEC_ENCRYPT_NO_MITM:
498ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        case GATT_SEC_ENCRYPT_MITM:
499ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            if (sec_act_old < GATT_SEC_ENCRYPT)
500ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            {
501b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                GATT_TRACE_DEBUG("gatt_security_check_start: Encrypt now or key upgreade first");
502ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                gatt_convert_sec_action(gatt_sec_act, &btm_ble_sec_act);
503f40b136e7b943d7e25224817fc47bb5b171479d5Andre Eisenbach                btm_status = BTM_SetEncryption(p_tcb->peer_bda, p_tcb->transport,
504f40b136e7b943d7e25224817fc47bb5b171479d5Andre Eisenbach                                               gatt_enc_cmpl_cback, NULL, btm_ble_sec_act);
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if ( (btm_status != BTM_SUCCESS) && (btm_status != BTM_CMD_STARTED))
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
507b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati                    GATT_TRACE_ERROR("gatt_security_check_start BTM_SetEncryption failed btm_status=%d", btm_status);
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    status = FALSE;
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
510ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            }
511ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            if (status)
512ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta                gatt_add_pending_enc_channel_clcb (p_tcb, p_clcb);
513ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            break;
514ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        case GATT_SEC_ENC_PENDING:
515ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            gatt_add_pending_enc_channel_clcb (p_tcb, p_clcb);
516ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            /* wait for link encrypotion to finish */
517ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            break;
518ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        default:
519ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            gatt_sec_check_complete(TRUE, p_clcb, gatt_sec_act);
520ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta            break;
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
522ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
523ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    if (status == FALSE)
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
525ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
526ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif  /* BLE_INCLUDED */
534