This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Protect only a few Bluetooth characteristics

Hello

I would like to protect some Bluetooth characteristics in order to protect them from eavesdropping.

In fact, here is my problem: I would like to make an application (on a smartphone) which allows to quickly connect in Bluetooth to the devices with range in order to just retrieve the value of a characteristic which is in "SEC_OPEN" and then to disconnect . On the other hand, I would also like to have characteristics which will be in "SEC_JUST_WORKS" in order to protect the communication which is done on these characteristics (these are the commands which will have to be executed by the device).

Here are my questions:
- Is it possible to connect to a device without having to do pairing in order to read a characteristic in "SEC_OPEN"? (while the "LE Secure Connection" is activated on the smartphone and the target device). The objective being that it is invisible for the user and that he does not have the need to pair.
- Is it normal that I see the same message twice on my smartphone when I connect to my device asking me if I want to pair the device?
I am using the following configuration on my device:

// Security parameters to be used for all security procedures.
sec_param.bond = false;
sec_param.mitm = false;
sec_param.lesc = 1;
sec_param.keypress = 0;
sec_param.io_caps = BLE_GAP_IO_CAPS_NONE;
sec_param.oob = false;
sec_param.min_key_size = 7;
sec_param.max_key_size = 16;
sec_param.kdist_own.enc = 0;
sec_param.kdist_own.id = 0;
sec_param.kdist_peer.enc = 0;
sec_param.kdist_peer.id = 0;


Thank you

  • Hi,

    - Is it possible to connect to a device without having to do pairing in order to read a characteristic in "SEC_OPEN"? (while the "LE Secure Connection" is activated on the smartphone and the target device). The objective being that it is invisible for the user and that he does not have the need to pair.

    Yes, that is no problem. Pairing is only required to access characteristics which are not open.

    - Is it normal that I see the same message twice on my smartphone when I connect to my device asking me if I want to pair the device?
    I am using the following configuration on my device:

    No, it does not seem expected. Perhaps it would be easier to understand what causes this if you have a log from the nRF and a sniffer trace, as well as a more detailed explanation on how this happens.

  • Here is my sniffer trace:
    Test_with_pairing.pcapng

    I have an error at the end (DHKey Check failed) but I think it's another problem. Do you have any idea what can cause this error?

    Thank you

  • Hi,

    I do not see why the DHKey check failed. Which SDK version are you using? Can you enable logging on the nRF side and share the log? Do you always see this, or only in some situations or with some specific centrals (some phones etc)?

  • Hi,

    My application is based on the example "ble_thread_dyn_mtd_coap_cli" (nRF5_SDK_for_Thread_and_Zigbee_v4.1.0). To secure the bluetooth connection, I tried to use the "ble_app_multirole_lesc" example but maybe I forgot some things? (for my application, I need to use the Just Works method for LE Secure Connections).

    Yes I still have the same problem when I connect. But it works with the "ble_app_multirole_lesc" example so I think the problem is in my source code.
    I connect to a Samsung S10 smartphone with nRF Connect.

    Here are the logs on the nRF side:

    <info> app: Connected
    <info> app: Data len is set to 0xF0(240)
    <info> nrf_ble_lesc: Calling sd_ble_gap_lesc_dhkey_reply on conn_handle: 0
    <info> app: BLE_GAP_EVT_AUTH_STATUS
    <info> app: Authorization failed with code: 139!
    <info> peer_manager_handler: Connection security failed: role: Peripheral, conn_handle: 0x0, procedure: Bonding, error: 139
    <info> app: Disconnected

    Do you want that I send you my project to make it easier (private project) or only specifics files or functions?

    In the meantime, here are some infos:

    2235.sdk_config.h

    /**@brief Function for handling Peer Manager events.
     *
     * @param[in] p_evt  Peer Manager event.
     */
    static void pm_evt_handler(pm_evt_t const * p_evt)
    {
        pm_handler_on_pm_evt(p_evt);
        //pm_handler_disconnect_on_sec_failure(p_evt);
        pm_handler_flash_clean(p_evt);
    
        switch (p_evt->evt_id)
        {
            case PM_EVT_PEERS_DELETE_SUCCEEDED:
                //adv_scan_start();
                //scan_start();
                break;
    
            default:
                break;
        }
    }
    
    void peer_manager_init(bool erase_bonds)
    {
        ble_gap_sec_params_t sec_param;
        ret_code_t err_code;
    
        err_code = pm_init();
        APP_ERROR_CHECK(err_code);
    
        if (erase_bonds)
        {
            err_code = pm_peers_delete();
            APP_ERROR_CHECK(err_code);
        }
        memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
        // Security parameters to be used for all security procedures.
        sec_param.bond = false;//true;
        sec_param.mitm = false;
        sec_param.lesc = 1;
        sec_param.keypress = 0;
        sec_param.io_caps = BLE_GAP_IO_CAPS_NONE;
        sec_param.oob = false;
        sec_param.min_key_size = 7;
        sec_param.max_key_size = 16;
        sec_param.kdist_own.enc = 0;//1;
        sec_param.kdist_own.id = 0;//1;
        sec_param.kdist_peer.enc = 0;//1;
        sec_param.kdist_peer.id = 0;//1;
    
        err_code = pm_sec_params_set(&sec_param);
        APP_ERROR_CHECK(err_code);
    
        err_code = pm_register(pm_evt_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        uint32_t err_code;
        ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
        //char  p_message_ble_gap_evt_connected[] = "Connected on bluetooth";
        //char  p_message_ble_gap_evt_disconnected[] = "Disconnected from bluetooth";
    
        #ifdef BLE_LE_SECURE_CONNECTIONS
            pm_handler_secure_on_connection(p_ble_evt);
        #endif
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                break;
    
    #ifdef BLE_LE_SECURE_CONNECTIONS
            case BLE_GAP_EVT_AUTH_STATUS:
                NRF_LOG_INFO("BLE_GAP_EVT_AUTH_STATUS");
                if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status ==
                    BLE_GAP_SEC_STATUS_SUCCESS)
                {
                    NRF_LOG_INFO("Authorization succeeded!");
                }
                else
                {
                    NRF_LOG_INFO("Authorization failed with code: %u!",
                                 p_ble_evt->evt.gap_evt.params.auth_status.auth_status);
                }
                break;
    
            /*#if !NFC_BLE_PAIR_LIB_ENABLED
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                // Pairing not supported
                err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
                APP_ERROR_CHECK(err_code);
                break;
            #endif*/
    #endif
    
    #ifndef BLE_LE_SECURE_CONNECTIONS
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                // Pairing not supported
                err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
                APP_ERROR_CHECK(err_code);
                break;
    #endif
    
             case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
            {
                ble_gap_data_length_params_t dl_params;
    
                // Clearing the struct will effectivly set members to @ref BLE_GAP_DATA_LENGTH_AUTO
                memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t));
                err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL);
                APP_ERROR_CHECK(err_code);
            } break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                NRF_LOG_DEBUG("PHY update request.");
                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
                APP_ERROR_CHECK(err_code);
            } break;
    
    #ifndef BLE_LE_SECURE_CONNECTIONS
            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
                // No system attributes have been stored.
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
                APP_ERROR_CHECK(err_code);
                break;
    #endif
    
            case BLE_GATTC_EVT_TIMEOUT:
                // Disconnect on GATT Client timeout event.
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_EVT_USER_MEM_REQUEST:
                err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
            {
                ble_gatts_evt_rw_authorize_request_t  req;
                ble_gatts_rw_authorize_reply_params_t auth_reply;
    
                req = p_ble_evt->evt.gatts_evt.params.authorize_request;
    
                if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
                {
                    if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)     ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                    {
                        if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                        }
                        else
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                        }
                        auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
                        err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                                   &auth_reply);
                        APP_ERROR_CHECK(err_code);
                    }
                }
            } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST
    
            default:
                // No implementation needed.
                break;
        }
    }


    Thank you

  • Hi,

    If you could upload your project that would be good. You can create a new private case where you upload it. Please refer to this thread in the new case so that it is assigned to me.

Related