Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d478943 authored by Mudumba Ananth's avatar Mudumba Ananth Committed by Andre Eisenbach
Browse files

BR/EDR secure connections support

As a part of BT 4.1 stack upgrade, added host support for BR/EDR
secure connections to be able to interact with controllers that
support secure connections and upgrade the SSP mechanism to use
secure connection rules.

This change checks for controller support in the extended_features
(LMP page 2) and then declares the host support (extended_features
LMP page 1) using WRITE SECURE CONNECTIONS HOST SUPPORT.
If both the sides support secure connections, the simple pairing
process utilizes the link key generated using P-256 elliptic curve
(in the controller) and both the sides will be
in a secure connection.

Bug: 19289699
Change-Id: Idb3c41f439973bea137f5a4a69468c1f55aecbd7
parent 1dccedaa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ typedef struct
#define BTA_SEC_AUTHORIZE       (BTM_SEC_IN_AUTHORIZE )                              /* Authorization required (only needed for out going connection )*/
#define BTA_SEC_AUTHENTICATE    (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE) /* Authentication required. */
#define BTA_SEC_ENCRYPT         (BTM_SEC_IN_ENCRYPT | BTM_SEC_OUT_ENCRYPT)           /* Encryption required. */
#define BTA_SEC_MODE4_LEVEL4    (BTM_SEC_MODE4_LEVEL4)                               /* Mode 4 level 4 service, i.e. incoming/outgoing MITM and P-256 encryption */

typedef UINT8 tBTA_SEC;

+6 −0
Original line number Diff line number Diff line
@@ -178,6 +178,12 @@ static future_t *start_up(void) {
    page_number++;
  }

  secure_connections_supported = HCI_SC_CTRLR_SUPPORTED(features_classic[2].as_array);
  if (secure_connections_supported) {
    response = AWAIT_COMMAND(packet_factory->make_write_secure_connections_host_support(HCI_SC_MODE_ENABLED));
    packet_parser->parse_generic_command_complete(response);
  }

#if (BLE_INCLUDED == TRUE)
  ble_supported = last_features_classic_page_index >= 1 && HCI_LE_HOST_SUPPORTED(features_classic[1].as_array);
  if (ble_supported) {
+39 −87
Original line number Diff line number Diff line
@@ -16,11 +16,19 @@
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  This file contains functions that handle ACL connections. This includes
 *  operations such as hold and sniff modes, supported packet types.
 *
/*****************************************************************************
**
**  Name:          btm_acl.c
**
**  Description:   This file contains functions that handle ACL connections.
**                 This includes operations such as hold and sniff modes,
**                 supported packet types.
**
**                 This module contains both internal and external (API)
**                 functions. External (API) functions are distinguishable
**                 by their names beginning with uppercase BTM.
**
**
******************************************************************************/

#include <stdlib.h>
@@ -42,8 +50,6 @@

static void btm_read_remote_features (UINT16 handle);
static void btm_read_remote_ext_features (UINT16 handle, UINT8 page_number);
static void btm_process_remote_ext_features_page (tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec,
                                                  UINT8 page_idx);
static void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages);

#define BTM_DEV_REPLY_TIMEOUT   3       /* 3 second timeout waiting for responses */
@@ -274,23 +280,23 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
            {
                /* If remote features already known, copy them and continue connection setup */
                if ((p_dev_rec->num_read_pages) &&
                    (p_dev_rec->num_read_pages <= (HCI_EXT_FEATURES_PAGE_MAX + 1)) /* sanity check */)
                    (p_dev_rec->num_read_pages <= (HCI_EXT_FEATURES_PAGE_MAX + 1)))
                {
                    memcpy (p->peer_lmp_features, p_dev_rec->features,
                        (HCI_FEATURE_BYTES_PER_PAGE * p_dev_rec->num_read_pages));
                    p->num_read_pages = p_dev_rec->num_read_pages;

                    if (BTM_SEC_MODE_SP == btm_cb.security_mode
                        && HCI_SSP_HOST_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_1])
                        && HCI_SIMPLE_PAIRING_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
                    {
                        p_dev_rec->sm4 = BTM_SM4_TRUE;
                    }
                    else
                    const UINT8 req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND);

                    /* Store the Peer Security Capabilites (in SM4 and rmt_sec_caps) */
                    btm_sec_set_peer_sec_caps(p, p_dev_rec);

                    BTM_TRACE_API("%s: pend:%d", __FUNCTION__, req_pend);
                    if (req_pend)
                    {
                        p_dev_rec->sm4 |= BTM_SM4_KNOWN;
                        /* Request for remaining Security Features (if any) */
                        l2cu_resubmit_pending_sec_req (p_dev_rec->bd_addr);
                    }

                    btm_establish_continue (p);
                    return;
                }
@@ -949,82 +955,28 @@ void btm_process_remote_ext_features (tACL_CONN *p_acl_cb, UINT8 num_read_pages)
    p_acl_cb->num_read_pages = num_read_pages;
    p_dev_rec->num_read_pages = num_read_pages;

    /* Process the pages one by one */
    /* Move the pages to placeholder */
    for (page_idx = 0; page_idx < num_read_pages; page_idx++)
    {
        btm_process_remote_ext_features_page (p_acl_cb, p_dev_rec, page_idx);
    }
}


/*******************************************************************************
**
** Function         btm_process_remote_ext_features_page
**
** Description      Local function called to process the information located
**                  in the specific extended features page read from a remote device.
**
** Returns          void
**
*******************************************************************************/
void btm_process_remote_ext_features_page (tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec,
                                           UINT8 page_idx)
        if (page_idx > HCI_EXT_FEATURES_PAGE_MAX)
        {
    UINT8             req_pend;

            BTM_TRACE_ERROR("%s: page=%d unexpected", __FUNCTION__, page_idx);
            break;
        }
        memcpy (p_dev_rec->features[page_idx], p_acl_cb->peer_lmp_features[page_idx],
                HCI_FEATURE_BYTES_PER_PAGE);

    switch (page_idx)
    {
    /* Extended (Legacy) Page 0 */
    case HCI_EXT_FEATURES_PAGE_0:
        /* Page 0 indicates Controller support for SSP */
        if (btm_cb.security_mode < BTM_SEC_MODE_SP ||
            !HCI_SIMPLE_PAIRING_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
        {
            req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND);
            p_dev_rec->sm4 = BTM_SM4_KNOWN;
            if (req_pend)
            {
                l2cu_resubmit_pending_sec_req (p_dev_rec->bd_addr);
    }
        }
        break;

    /* Extended Page 1 */
    case HCI_EXT_FEATURES_PAGE_1:
        /* Page 1 indicates Host support for SSP and SC */
        req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND);

        if (btm_cb.security_mode == BTM_SEC_MODE_SP
            && HCI_SSP_HOST_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_1])
            && HCI_SIMPLE_PAIRING_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
        {
            p_dev_rec->sm4 = BTM_SM4_TRUE;
        }
        else
        {
            p_dev_rec->sm4 = BTM_SM4_KNOWN;
        }
    const UINT8 req_pend = (p_dev_rec->sm4 & BTM_SM4_REQ_PEND);

        BTM_TRACE_API ("ext_features_complt page_num:%d f[0]:x%02x, sm4:%x, pend:%d",
                        HCI_EXT_FEATURES_PAGE_1, *(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_1]),
                        p_dev_rec->sm4, req_pend);
    /* Store the Peer Security Capabilites (in SM4 and rmt_sec_caps) */
    btm_sec_set_peer_sec_caps(p_acl_cb, p_dev_rec);

    BTM_TRACE_API("%s: pend:%d", __FUNCTION__, req_pend);
    if (req_pend)
    {
        /* Request for remaining Security Features (if any) */
        l2cu_resubmit_pending_sec_req (p_dev_rec->bd_addr);

        break;

    /* Extended Page 2 */
    case HCI_EXT_FEATURES_PAGE_2:
        /* Page 2 indicates Ping support*/
        break;

    default:
        BTM_TRACE_ERROR("btm_process_remote_ext_features_page page=%d unexpected", page_idx);
        break;
    }
}

+9 −0
Original line number Diff line number Diff line
@@ -189,6 +189,9 @@ BT_OCTET16 ble_encryption_key_value; /* BLE encryption key */

    tBTM_IO_CAP          loc_io_caps;       /* IO capability of the local device */
    tBTM_AUTH_REQ        loc_auth_req;      /* the auth_req flag  */
    BOOLEAN              secure_connections_only;    /* Rejects service level 0 connections if */
                                                     /* itself or peer device doesn't support */
                                                     /* secure connections */
} tBTM_DEVCB;


@@ -565,6 +568,11 @@ typedef struct
    UINT8       sm4;                    /* BTM_SM4_TRUE, if the peer supports SM4 */
    tBTM_IO_CAP rmt_io_caps;            /* IO capability of the peer device */
    tBTM_AUTH_REQ rmt_auth_req;         /* the auth_req flag as in the IO caps rsp evt */
    BOOLEAN     remote_supports_secure_connections;
    BOOLEAN     remote_features_needed; /* set to true if the local device is in */
                                        /* "Secure Connections Only" mode and it receives */
                                        /* HCI_IO_CAPABILITY_REQUEST_EVT from the peer before */
                                        /* it knows peer's support for Secure Connections */

#if (BLE_INCLUDED == TRUE)
    UINT16              ble_hci_handle;         /* use in DUMO connection */
@@ -1056,6 +1064,7 @@ extern void btm_sec_link_key_request (UINT8 *p_bda);
extern void  btm_sec_pin_code_request (UINT8 *p_bda);
extern void  btm_sec_update_clock_offset (UINT16 handle, UINT16 clock_offset);
extern void  btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN is_le_trasnport);
extern void btm_sec_set_peer_sec_caps (tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec);

#if BLE_INCLUDED == TRUE
extern void  btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC  *p_dev_rec);
+23 −0
Original line number Diff line number Diff line
@@ -434,6 +434,29 @@ static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle,
                temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 |
                                   HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5);
            }

             /* Check to see if BR/EDR Secure Connections is being used
             ** If so, we cannot use SCO-only packet types (HFP 1.7)
             */
            if (BTM_BothEndsSupportSecureConnections(p_acl->remote_addr))
            {
                temp_pkt_types &= ~(BTM_SCO_PKT_TYPE_MASK);
                BTM_TRACE_DEBUG("%s: SCO Conn: pkt_types after removing SCO (0x%04x)", __FUNCTION__,
                                 temp_pkt_types);

                /* Return error if no packet types left */
                if (temp_pkt_types == 0)
                {
                    BTM_TRACE_ERROR("%s: SCO Conn (BR/EDR SC): No packet types available",
                                    __FUNCTION__);
                    return (BTM_WRONG_MODE);
                }
            }
            else
            {
                BTM_TRACE_DEBUG("%s: SCO Conn(BR/EDR SC):local or peer does not support BR/EDR SC",
                                __FUNCTION__);
            }
        }


Loading