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 !

  • 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.

  • 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.

  • Hi Kenneth,

    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. 

    I have implemented the same OOB Legacy Pairing with preshared key as you mentioned here. But the OOB key with Zero (as shown in below) only works

    static ble_advdata_tk_value_t m_oob_auth_key = {
    .tk = { 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00}
    };

    Feed key 00000000000000000000000000000000

    but when I try it with numbers other than zero it is not working....Could you please suggest any solution here, why this happening like this..?

    Thanks and Regards,

    Sreejith

Reply
  • Hi Kenneth,

    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. 

    I have implemented the same OOB Legacy Pairing with preshared key as you mentioned here. But the OOB key with Zero (as shown in below) only works

    static ble_advdata_tk_value_t m_oob_auth_key = {
    .tk = { 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00}
    };

    Feed key 00000000000000000000000000000000

    but when I try it with numbers other than zero it is not working....Could you please suggest any solution here, why this happening like this..?

    Thanks and Regards,

    Sreejith

Children
  • Are you controlling both sides of the link? E.g. have you updated the project to use preshared keys on both peripheral and central? Maybe check that SDK v13 example works before you try to update one of the sides to a newer SDK.

    Kenneth

  • Hi Kenneth,

    Are you controlling both sides of the link?

    Indirectly yes, I am programming the peripheral only, but Master side also programms with the mutual understand in order to connect with OOB Legacy Pairing with 128 bit Security key /Preshared Key. 

    E.g. have you updated the project to use preshared keys on both peripheral and central?

    I am programming only the peripheral, therefore I am doing test with the help of nRF52840 Dongle and nRF Connect Desktop (not programms Master)

    Maybe check that SDK v13 example works before you try to update one of the sides to a newer SDK.

    I am working with nRF SDK v17.

    simply it works, when the 128 bit key is Zeros but not pairing when any other number present in key other than Zero..

    thanks and Regards,

    Sreejith

  • I recommend to get the SDKv13 up and running for comparison. 

    Can the problem be related to endianness? e.g. does using AAAAAA..AAA work?

    Kenneth

  • Hi,

    Can the problem be related to endianness? e.g. does using AAAAAA..AAA work?

    I tried with following keys,

    /***ADDED CODE ***/
    static ble_advdata_tk_value_t m_oob_auth_key = {
    .tk = { 0x11, 0x11, 0x11, 0x11,
    0x11, 0x11, 0x11, 0x11,
    0x11, 0x11, 0x11, 0x11,
    0x11, 0x11, 0x11, 0x11}
    };

    Fed key: 11111111111111111111111111111111

    and

    /***ADDED CODE ***/
    static ble_advdata_tk_value_t m_oob_auth_key = {
    .tk = { 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01}
    };

    fed key: 01010101010101010101010101010101

    also tried here key: 10101010101010101010101010101010

    in all these above given stage it did not paired....That means the only connects when all numbers are Zeroes...if any number other than zero present in the key, then it will not connect....

    Thanks and Regards,

    Sreejith

  • I notice you have a private case open regarding the same issue you experience with OOB. 

    From the private case I can see that 00000...000 means that it is not actually using OOB, but "just works" bonding. This will explain why it seemingly work with 00000...000, but not other keys.

    It might be an issue with nRF Connect for desktop in this case. I expect you will not use nRF Connect for desktop in your final application, so I suggest you use an nRF52 instead as a central device here, or a peer that you know you can inject OOB keys the same way.

    In any case, I suggest you handle your issue in the other private case you have, since this thread you are using here is really resolved.

    Kenneth

Related