Force bonding on a device only having a NUS service

My nRF52 only advertises NUS.

When a phone connects (Android or iPhone), I want to force bonding.

It seems to be related to security. I have tried a couple things, but I am unsure how to proceed. What should I do? Use LESC? MITM? Use BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM on NUS? (is it even feasible?)

I also need to add that my device doesn't have any external interface (no screen for instance).

Any guidance will be appreciated, thanks.

Parents
  • Hello,

    MITM protection is not possible when you don't have any relevant IO capabilities (display, keyboard, etc), so BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM ("just works") is probably the best you are going to get. You can enable LESC to get protection against passive eavesdropping (I.e. A BT sniffer will not be able to pick up the encryption key during the DH key exchange).

    But have you integrated the Peer Manager module in your application? This is needed to handle to manage bonding on the device. If not, it's often easier to start with an example that already supports it like the ble_app_hrs example, then add the NUS service as opposed to integrating all the peer manager and crypto dependencies in the ble_app_uart project.

    Best regards,

    Vidar

  • Thank you very much for your answer Vidar!

    Yes, I forked the app_hrs example and I have a working Peer Manager (with only one bond allowed).

    I enabled LESC by setting

    #define SEC_PARAM_LESC to 1

    and

    sec_param.lesc           = SEC_PARAM_LESC;

    Could you tell me how to use BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM with NUS?

    Thanks again,

  • es, NUS is one of our few service implementations that don't expose the security levels as an init parameter. You can always make a copy of the NUS service and keep it in the project directory so you don't have to modify the SDK itself.

    That's what I did, thanks.

    s it a pairing request? In that case, try to comment the call to pm_handler_on_pm_evt() or pm_handler_secure_on_connection() if you have it in your Peer manager callback. This should stop the peripheral from issuing a security request to the phone, and rather wait for the phone to initiate it.

    I commented out pm_handler_on_pm_evt() but I cannot connect anymore. If I try send data, I get an NRF_ERROR_INVALID_STATE. Here is my callback:

    static void pm_evt_handler(pm_evt_t const * p_evt)
    {
        //pm_handler_on_pm_evt(p_evt);
        pm_handler_flash_clean(p_evt);
    
        switch (p_evt->evt_id)
        {
            case PM_EVT_CONN_SEC_SUCCEEDED:
                m_peer_id = p_evt->peer_id;
                break;
    
            case PM_EVT_PEERS_DELETE_SUCCEEDED:
                advertising_start(false);
                break;
    
            case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
                if (     p_evt->params.peer_data_update_succeeded.flash_changed
                     && (p_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_BONDING))
                {
                    NRF_LOG_INFO("New Bond, add the peer to the whitelist if possible");
                    // Note: You should check on what kind of white list policy your application should use.
    
                    whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
                }
                break;
    
            case PM_EVT_CONN_SEC_CONFIG_REQ:
                {
                    // Reject pairing request from an already bonded peer.
                    pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
                    pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
                } break;
    
            default:
                break;
        }
    }

  • I doubt it has anything to do with you commenting the pm_handler_on_pm_evt() line. Does you device advertise with Whitelist? If so, are you able to connect if you disable it?

  • Hi Vidar, sorry I was sucked into other things.

    To sum up:

    1. I have a BLE peripheral with a whitelist. BLE_GAP_WHITELIST_ADDR_MAX_COUNT = 1
    2. I forked ble_nus.c and changed the five SEC_OPEN to SEC_JUST_WORKS as you suggested, and have the following security paramters:
      #define SEC_PARAM_BOND                      1                                       /**< Perform bonding. */
      #define SEC_PARAM_MITM                      0                                       /**< Man In The Middle protection not required. */
      #define SEC_PARAM_LESC                      1                                       /**< LE Secure Connections enabled. */
      #define SEC_PARAM_KEYPRESS                  0                                       /**< Keypress notifications not enabled. */
      #define SEC_PARAM_IO_CAPABILITIES           BLE_GAP_IO_CAPS_NONE                    /**< No I/O capabilities. */
      #define SEC_PARAM_OOB                       0                                       /**< Out Of Band data not available. */

    If I try to connect, I get a popup, but then nothing happens. Sending results in NRF_ERROR_INVALID_STATE. I get the following log:

    00> <info> peer_manager_handler: Connection security failed: role: Peripheral, conn_handle: 0x0, procedure: Bonding, error: 1

    I tried commenting off the call to pm_handler_on_pm_evt, nothing happens, and without the log. Same state error.

    All the code was imported from the SDK.

    Would you have any idea about what's happening?

  • Hi,

    No worries. Are you calling nrf_ble_lesc_request_handler() from your main loop? Error one indicates a procedure timeout (BLE_GAP_SEC_STATUS_TIMEOUT), and could happen if the lesc events are not being processed. 

  • I added that function in main loop and it seems to work. I need to run more tests across platforms but I think I'm seeing the end. Thanks a lot again Vidar.

Reply Children
Related