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 !

  • 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 ?
  • The examples I shared should work out of the box, but it is for a slightly older SDK, so it may need some modifications.

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

    If you set a specific security level for a characteristic, then there is no data exchanged on that characteristic until the security level on the link is met. When this occurs depends on how you want it to behave; you can bond before accessing characteristics or you can wait until you get an insufficient security level error when accessing the characteristic.

  • Another question : about the sd_ble_gap_sec_params_reply function, when I call it in the BLE_GAP_EVT_SEC_PARAMS_REQUEST event, I don't really understand how to fill the last parameter, sec_keyset.

    What is own ? what is peer ?

    How do i fill enc_key ? Have I to do it ?

    sames questions for id_key, and sign_key.

  • Basically what is done here is that you provide a buffer to the softdevice. This buffer is filled with keys  by the softdevice when the BLE_GAP_EVT_AUTH_STATUS even occurs.

    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s132.api.v7.2.0/group___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 

    I strongly recommend using peer manager to handle this for you.

Reply Children
  • Yeah, but in the parameters, it is written that this is a In/out parameter, so I can fill it before calling the function. But with what ?

    I strongly recommend using peer manager to handle this for you.

    Ok, but I need to know if we don't bond, is it possible to handle the security without the peer_manager, with handling only the BLE_GAP_EVT_SEC_PARAMS_REQUEST event and BLE_GAP_EVT_AUTH_KEY_REQUEST event ? I am asking that because in my program ( not in the hrs examples), i have still the problem about the ram address.

    And another question :

    With my security parameters, so :

    • Legacy connection
    • No bonding
    • Pairing with OOB with keys stored on the central and the peripheral

    Which security parameter do I have to choose to secure my attributes :

    SEC_JUST_WORKS or SEC_MITM ? or another ?

    I am asking that because, it seems to  me that I have to use the SEC_MITM security, but when I do that, I cannot receive the notifications with the hrs example. But it seems also to me that the SEC_JUST_WORKS security don't use the OOB.

Related