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

Bonding. Why ltk changed at every reconnection?

Hi, I have done the bonding and saving context to flash. As an example I used ble_app_template. I cutted all redundant code and limited to single bond for simplicity. In my code I save next:

 - m_connection_table (I changed it a little bit)
 - m_peer_table 
 - m_bond_table (i.e. ble_gap_enc_key_t, LTK)

At device startup I load m_peer_table to know what peer address I'm waiting to connect. Advertice Than after peer connect I load m_bond_table with presaved LTK. At BLE_GAP_EVT_SEC_PARAMS_REQUEST peer central gives:

ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.enc   - 1
  ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_central.id     - 0
  ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.sign   - 1
  ble_evt->evt.gap_evt.params.sec_params_request.peer_params.bond   - 1

My local setup is

m_sec_params.kdist_periph.enc   = 1;
m_sec_params.kdist_periph.id    = 0;
m_sec_params.kdist_periph.sign  = 0; //Not supported yet

At BLE_GAP_EVT_CONN_SEC_UPDATE Established Mode 0x01, Level 0x02 - so link is encrpted.Here I apply service context.

At BLE_GAP_EVT_AUTH_STATUS if bond successfull I save context to nonvolatile memory. But here the LTK is different whan I sent as reply to BLE_GAP_EVT_SEC_PARAMS_REQUEST.

After host disconnected I save all context similar to at BLE_GAP_EVT_AUTH_STATUS event.

As I understand LTK have to be constant for long time, so why it changes at each reconnection? It seem that I repeat bonding procedure each time at connection because I do not receive BLE_GAP_EVT_SEC_INFO_REQUEST at reconnect as stated here [https://devzone.nordicsemi.com/documentation/nrf51/4.4.0/html/group___b_o_n_d_e_d___m_a_s_t_e_r.html] or here [https://devzone.nordicsemi.com/documentation/nrf51/6.0.0/s110/html/a00824.html]

  • What SDK and SoftDevice version are you using? Are you using the device manager? What is your central device? Have you tried to sniff to see what is happening on air?

  • Both S110 and S130 were tried on nRF51422QFAAE0. I neither use SDK nor Device manager. I interact with sotdevice only within sd_ble_... functions. What should I see if sniff the air? In debug I ablle to see all BLE events to compare with flowcharts from mentioned above document references. As central do not sent the BLE_GAP_EVT_SEC_INFO_REQUEST after connection may I suppose that it doesn't remember the bond?

  • The peripheral application will receive the BLE_GAP_EVT_SEC_INFO_REQUEST event if it gets a pairing encryption request, which the central sends if the central application calls sd_ble_gap_encrypt(). Is your central application calling this?

  • Sorry for late responce. I have made some experiments. My issue connected with loss of bond information on master or slave. If bond saved and loaded correctly I receive BLE_GAP_EVT_SEC_INFO_REQUEST. About pairing encryption request, for Windows 8.1 it seems that I can't make any impact on bonding process so I can't generate this request. If you mean air sniffing, I need some data about this request first.

    • I tested on Win8.1 and it works, on Nexus7 doesn't. The test case was the next:
    1. bonding

    2. disconnection from host by switching off bluetooth or removing the BLE dongle.

    3. On periperal wthite list become working and after switching on bluetooth on central, it connects and in one case rebonds with new LTK, in other case using previous bond.

    When I receive BLE_GAP_EVT_DISCONNECTED the ble_evt->evt.gap_evt.params.disconnected.reason is BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION for Nexus7 and BLE_HCI_CONNECTION_TIMEOUT for Win8.1. Could this parameter be connected with described issue?


    I think I found. In Android code each time I connected the method called

    device.createBond();
    

    Now it changed to and seems to work properly, but it not always define bond status correctly(((

    if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
        device.createBond();
    } 
    
Related