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

Modify pre shared OOB key for Legacy Connection

Hi !

I am working on SDK 15.2 and on a NRF52832.

The others devices I will interact with are on BLE 4, so I can use only Legacy Connection mode for security. 

I would like to use Out of Band mode, with a pre shared key stored on my device. The other device, a BLE Gateway, will have a file with this key stored too. 

First, I would like to know if there are examples to do that. 

Second, i would like to know if it is possible to modify the value of the key and keep its value even if we switch off the device. 

Thanks,

Parents
  • Hi,

    It is possible to use pre-shared OOB keys yes. I made an example for nRF5 SDK v13 that show this, in principle it should be the same for more recent nRF5 SDK also. You will need to handle the BLE_GAP_EVT_AUTH_KEY_REQUEST in on_ble_evt() on both the central and peripheral device. 

    \nRF5_SDK_13.0.0_04a0bfd\examples\ble_central\ble_app_hrs_c

    \nRF5_SDK_13.0.0_04a0bfd\examples\ble_peripheral\ble_app_hrs

    ble_app_hrs_c.zip

    ble_app_hrs.zip

    Here is a more updated message sequence chart:

    https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s132.api.v7.2.0%2Fgroup___b_l_e___g_a_p___p_e_r_i_p_h___b_o_n_d_i_n_g___p_k___c_e_n_t_r_a_l___o_o_b___m_s_c.html

    https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s132.api.v7.2.0%2Fgroup___b_l_e___g_a_p___c_e_n_t_r_a_l___b_o_n_d_i_n_g___p_k___p_e_r_i_p_h___o_o_b___m_s_c.html

    Best regards,
    Kenneth

  • Hi Kenneth, sorry for the delay, finally it was not a priority for us 2 months ago. But now I need to come back to it.

    So I have read the ble_app_hrs example and have taken few pieces of program. I have added this code in my program :

    //AKR
    /**@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:
            {
                advertising_start();
            }
            break;
    
            default:
            {
            }
            break;
        }
    }
    
    //AKR
    /**@brief Function for the Peer Manager initialization.
     */
    static void peer_manager_init(void)
    {
        ble_gap_sec_params_t sec_param;
        ret_code_t           err_code;
    
        err_code = pm_init();
        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           = SEC_PARAM_BOND;
        sec_param.mitm           = SEC_PARAM_MITM;
        sec_param.lesc           = SEC_PARAM_LESC;
        sec_param.keypress       = SEC_PARAM_KEYPRESS;
        sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
        sec_param.oob            = SEC_PARAM_OOB;
        sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
        sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
        sec_param.kdist_own.enc  = 0;
        sec_param.kdist_own.id   = 0;
        sec_param.kdist_peer.enc = 0;
        sec_param.kdist_peer.id  = 0;
    
        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);
    }

    I have called it in my main function.

    Here is how I handle the BLE_GAP_EVT_AUTH_KEY_REQUEST event:

            // Upon authentication key request, reply with the preshared key in the device. //AKR
            case BLE_GAP_EVT_AUTH_KEY_REQUEST:
            {
    
                NRF_LOG_INFO("BLE_GAP_EVT_AUTH_KEY_REQUEST");
    
                err_code = sd_ble_gap_auth_key_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                     BLE_GAP_AUTH_KEY_TYPE_OOB,
                                                     key_auth);
                APP_ERROR_CHECK(err_code);
            }
            break;

    Also I have activated few stuffs in sdk_config to correctly build

    #define PEER_MANAGER_ENABLED 1

    #define PM_SERVICE_CHANGED_ENABLED 1

    #define FDS_ENABLED 1

    #define NRF_FSTORAGE_ENABLED 1

    It builds correctly, but when I launch my application, I have a problem with the  ble_stack_init function:

    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    void ble_stack_init(void)
    {
        extern uint8_t __data_start__;
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t app_ram_base = 0;
    
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &app_ram_base);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&app_ram_base);
    
        // Check if we do memory allocation correctly.
        if (err_code == NRF_SUCCESS)
        {
            // Verify that value provided in linked script (LD file) matches the SD calculations.
            if (app_ram_base == (uint32_t) &__data_start__)
            {
                //NRF_LOG_INFO("Soft Device enabled, __data_start__ is set correctly.");
                printf("Soft Device enabled, __data_start__ is set correctly.\n");
            }
            else
            {
                //NRF_LOG_INFO("Soft Device enabled, __data_start__ is set incorrectly (should be = 0x%08X instead of 0x%08X).", app_ram_base, (uint32_t) &__data_start__);
                printf("Soft Device enabled, __data_start__ is set incorrectly (should be = 0x%08X instead of 0x%08X).\n", app_ram_base, (uint32_t) &__data_start__);
                APP_ERROR_CHECK(NRF_ERROR_FORBIDDEN);
            }
        }
        else if (err_code == NRF_ERROR_NO_MEM)
        {
            // Not enough memory for the Soft Device (value provided is too low).
            //NRF_LOG_INFO("Soft Device failed to enabled, __data_start__ is set incorrectly (should be = 0x%08X instead of 0x%08X).", app_ram_base, (uint32_t) &__data_start__);
        }
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }

    app_ram_base and __data_start are different, app_ram_base = 0x2000 38C0 and __data_start  = 0x200038D4.

    However, I have declared RAM_START = 0x2000 38C0. Do you know why I have this error and how i can handle it ?

    Thanks !

  • Also I have a question about the message sequence chart for the peripheral :

    I see that I have to handle to events, BLE_GAP_EVT_SEC_PARAMS_REQUEST, and BLE_GAP_EVT_AUTH_KEY_REQUEST.

    For the BLE_GAP_EVT_SEC_PARAMS_REQUEST event, the chart says that I have to call the sd_ble_gap_sec_params_reply function, and for this function it is said in the documentation that the last parameter is [in/out], but I don't know how to fill it. It is not indicated in the documentation, can you help me about that ?

  • If you include peer manager, then it will handle most of these events already (e.g. BLE_GAP_EVT_SEC_PARAMS_REQUEST):
    https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/lib_peer_manager.html

    The input/output passkey, display, oob are really the only exceptions I can think of. 

  • Ok, so for now I am trying to use the ble_app_hrs with Legacy connection and OOB. I have filled the security parameters as it is told in the peer-manager documentation. I have handled the BLE_GAP_EVT_AUTH_KEY_REQUEST by adding the call of the sd_ble_gap_auth_key_reply function.I have also modified the battery service to put the SEC_MITM security level for the read access.

    I have also modified the battery service to put the SEC_MITM security level for the read access.

    To connect to my device, I use for now my phone with the nrfConnect app.

    After doing that, I am not sure what i have to wait for. I can still connect to my device without any key asked. have checked, I don't enter in the event handler for the BLE_GAP_EVT_AUTH_KEY_REQUEST.

    Wha I have to do to enter in this event so I can send my OOB key ?

    When I connect to my device, I have this message from the peer_manager_handler : 

    <info> peer_manager_handler: Connection secured: role: Peripheral, conn_handle: 0, procedure: Encryption

    Is the security only applied when we want to read/write the attributes ?

    Then I have tried to read the Battery value, but nothing is happening., I cannot read the value and nothing is printed on the debug terminal so I have no information.

    Do you know what I have to do ?

  • If you want to bond with a phone using OOB, then you need to use NFC. I believe there is a HRS example in the nRF5 SDK that can do this for you (\ble_app_hrs_nfc_pairing). You have very little control of this, since it\s handled by the OS. Likely you will not be able to do OOB unless you have NFC in the first place (it's not possible to inject OOB from the app afaik). Also, the trigger to execute bonding is depending on the OS on the phone. 

  • Well I want to use OOB, but without NFC. In the future, my peripheral will be connected with a BLE gateway, so I can simulate it for now with a pca10040. Can I use the ble_app_hrs_c example directly or do I have to modify it also ?

    And what about my other question :

    Is the security only applied when we want to read/write the attributes ?
Reply Children
Related