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

sd_ble_gap_encrypt() does not seem to encrypt link after bonding done

Hello,

I'm working with a nrf51822, SoftDevice S120 v2.0 and SDK v9.0 platform. Specifically using it a Central role to connect to a commercial Blood Pressure peripheral.

My peripheral has 2 distinct "modes":

  1. Pairing Mode - here is where you need to pair and bond to it. In this mode you can only bond and access certain protected characteristics (like Battery Level). I have to press a special button to put it into this Pairing mode.

  2. Reading Mode - here is where you just need to encrypt and get the readings from all it's protected characteristics

I have managed to successfully go through Pairing mode and create a bond thanks to the help I got from this post: devzone.nordicsemi.com/.../

As part of the successful authenticating and bonding process in Pairing Mode, sd_ble_gap_encrypt() was called and BLE_GAP_EVT_CONN_SEC_UPDATE was returned with :

p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv = 2

This indicted a successful encryption and it went on and completed authenticating and bonding. Bond information was then saved in the central. During this phase as the link was encrypted I was also able to read the protected Battery Level characteristic.

I then put the Peripheral in Reading Mode: Everything seems to flow fine (i.e. the Peripheral is matched to the Bond and the device manager puts it straight into Encryption using bond information). This flow happens:

  • Central finds Peripheral and Connects
  • get DM_EVT_DEVICE_CONTEXT_LOADED
  • get DM_EVT_SECURITY_SETUP (from the peripheral to request security process to start)
  • call dm_security_setup_req()
  • dm_security_setup_req() says "Already bonded device, encrypt the link."
  • sd_ble_gap_encrypt() is then called
  • get DM_EVT_SECURITY_SETUP with the values:

p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv = 1;

p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm = 1;

(m_connection_table[index].state & STATE_BONDED) = 0x08;

  • it then flags that the .lv is not 2 and goes into the "Lost bond case, generate a security refresh event!" flow which calls sd_ble_gap_authenticate() again due to start_sec_procedure being set to true
  • The process then errors out with the BLE_GAP_SEC_STATUS_AUTH_REQ error (probably because the Peripheral does not allow for pairing and bonding when in Reading Mode).

I have tried a few things already but have had no success, I have tried:

  • I ignored the the fact that BLE_GAP_EVT_CONN_SEC_UPDATE returned sec_mode.lv = 1 and forced it to continue with the process (i.e. making the DM go into the DM_EVT_LINK_SECURED block) and then tried to read the Battery Level of the Peripheral, but as expected it said "BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION"

The problem seems to be that, when using bond info to sd_ble_gap_encrypt() it does not seem to work.

Also not sure if its relevant or not but my sec_params in DM when authenticating/bonding was:

SEC_PARAM_BOND  1. 
SEC_PARAM_MITM  0. 
SEC_PARAM_IO_CAPABILITIES  BLE_GAP_IO_CAPS_NONE. 
SEC_PARAM_OOB  0. 
SEC_PARAM_MIN_KEY_SIZE   7.  
SEC_PARAM_MAX_KEY_SIZE  16.

Also based on the "GAP Central Encryption Establishment using stored keys" MSC developer.nordicsemi.com/.../a00780.html when BLE_GAP_EVT_CONN_SEC_UPDATE is sent by SD it means that the link was encrypted using the LTK or it was rejected due to a missing key. Not sure how to detect the failure reason.

Any idea what may be wrong?

Thanks very much.

Parents
  • Yes, it's confirmed @Petter. I got it working.

    What I was missing was these 2 lines in my code:

    register_param.sec_param.kdist_periph.enc = 1; 
    register_param.sec_param.kdist_periph.id = 1;
    

    I'm not sure why I need to set kdist_periph values instead of kdist_central values (as I'm working on a central) - but it works :)

    Thanks very much for your support on all the questions I had raised.

Reply
  • Yes, it's confirmed @Petter. I got it working.

    What I was missing was these 2 lines in my code:

    register_param.sec_param.kdist_periph.enc = 1; 
    register_param.sec_param.kdist_periph.id = 1;
    

    I'm not sure why I need to set kdist_periph values instead of kdist_central values (as I'm working on a central) - but it works :)

    Thanks very much for your support on all the questions I had raised.

Children
Related