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

LESC authentication for just exchanging IRK with enc key set to 0 seems to exchange LTK

I am attempting to use an nRF52840 with softdevice 7.2.0 to validate some scenarios and am seeing a difference in operation between legacy pairing and LESC pairings. I have tested against an nRF52840, iPhone (with LESC) and Android phone (without LESC). I set the key distribution to have id = 1 and all other fields = 0 on the device. In legacy mode, I get the authentication complete process and am getting the same values back in the params.auth_status.kdist_own and params.auth_status.kdist_peer parameters in the BLE_GAP_EVT_AUTH_STATUS event, however if the remote device supports LESC then I get id = 1 and enc = 1 in the params.auth_status.kdist_own field in this callback, even though I specified not to exchange the enc key by setting s_sec_params.kdist_own.enc = 0, I am still getting id = 1 and all other fields = 0 for the params.auth_status.kdist_peer parameter.

Is this expected or is something amiss in this?

Parents
  • Hi,

    I am not able to reproduce this, though I am not sure I understood. I tested a very slightly modified HRS example from SDK 17 where I changed to S140 7.2.0 (ble_app_hrs_s140_720.zip), and  set the enc fields to 0, like this:

    diff --git a/examples/ble_peripheral/ble_app_hrs/main.c b/examples/ble_peripheral/ble_app_hrs/main.c
    index a379c77..795951e 100644
    --- a/examples/ble_peripheral/ble_app_hrs/main.c
    +++ b/examples/ble_peripheral/ble_app_hrs/main.c
    @@ -847,9 +847,9 @@ static void peer_manager_init(void)
         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  = 1;
    +    sec_param.kdist_own.enc  = 0;
         sec_param.kdist_own.id   = 1;
    -    sec_param.kdist_peer.enc = 1;
    +    sec_param.kdist_peer.enc = 0;
         sec_param.kdist_peer.id  = 1;
     
         err_code = pm_sec_params_set(&sec_param);
    

    And with that, the kdist fields were set to 0. See log:

    <info> app_timer: RTC: initialized.
    <info> app: Heart Rate Sensor example started.
    <info> app: Fast advertising.
    <info> app: Connected.
    <info> app: GATT ATT MTU on connection 0x0 changed to 247.
    <info> app: BLE_GAP_EVT_LESC_DHKEY_REQUEST
    <info> nrf_ble_lesc: Calling sd_ble_gap_lesc_dhkey_reply on conn_handle: 0
    <info> peer_manager_handler: Connection secured: role: Peripheral, conn_handle: 0, procedure: Pairing
    <info> app: BLE_GAP_EVT_AUTH_STATUS: status=0x0 bond=0x0 lv4: 0 kdist_own:0x0 kdist_peer:0x0

    Is this what you mean, or are you testing another configuration and/or expecting another result?

  • Hi Einar,

    I've tested with the same modifications to the hrs central and hrs peripheral applications and tested them and this is what I am seeing:

    <info> app_timer: RTC: initialized.
    <info> app: Heart Rate collector example started.
    <info> app: Starting scan.
    <info> app: Connected.
    <info> app: GATT ATT MTU on connection 0x0 changed to 247.
    <info> app: Data length for connection 0x0 updated to 251.
    <info> app: BLE_GAP_EVT_LESC_DHKEY_REQUEST
    <info> app: Battery Level Read as 96 %.
    <info> nrf_ble_lesc: Calling sd_ble_gap_lesc_dhkey_reply on conn_handle: 0
    <info> peer_manager_handler: Connection secured: role: Central, conn_handle: 0, procedure: Bonding
    <info> app: BLE_GAP_EVT_AUTH_STATUS: status=0x0 bond=0x1 lv4: 0 kdist_own:0x3 kdist_peer:0x2
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Bonding data, action: Update
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Central address resolution, action: Update
    

    <info> app_timer: RTC: initialized.
    <info> app: Heart Rate Sensor example started.
    <info> app: Fast advertising.
    <info> app: Connected.
    <info> app: GATT ATT MTU on connection 0x0 changed to 247.
    <info> app: BLE_GAP_EVT_LESC_DHKEY_REQUEST
    <info> nrf_ble_lesc: Calling sd_ble_gap_lesc_dhkey_reply on conn_handle: 0
    <info> peer_manager_handler: Connection secured: role: Peripheral, conn_handle: 0, procedure: Bonding
    <info> app: BLE_GAP_EVT_AUTH_STATUS: status=0x0 bond=0x1 lv4: 0 kdist_own:0x3 kdist_peer:0x2
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Bonding data, action: Update
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Local database, action: Update
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Central address resolution, action: Update

    So I am seeing kdist_own as 0x3 (indicating LTK and IRK were exchanged) and kdist_peer as 0x2 (indicating IRK), I am expecting both sides and both values to be 0x2 as only the IRK should be getting exchanged but each side is showing it's own own LTK was exchanged which is not correct. You are getting 0 for both which doesn't add up as no IRK is being exchanged when it has been requested.

    Thanks,
    Jamie

  • Hi Jamie,

    Yes, my testing was a bit too quick.

    The reason is found in the API documentation for ble_gap_evt_auth_status_t::kdist_own:

    If bonding with LE Secure Connections, the enc bit will be always set.

    It does not really matter if this bit was set or unset as it does not provide any information in LESC (where the LTK is not exchanged anyway as it is derived using a Diffie–Hellman key exchange).

  • Hi Einar,

    When saving bond details then, is the right logic to follow this:

    if (lesc)
    {
        if (peer.enc)
        {
            SaveBond();
        }
    }
    else
    {
        if (peer.enc || own.enc)
        {
            SaveBond();
        }
    }

    Basically, how does the device know if it is a pairing or bonding and what details to save through LESC (if the exchange is just for IRK how does it know just to save the IRK only)?

    Thanks,
    Jamie

  • Hi Jamie,

    I think the problem is a bit odd to begin with. If you do not intend to encrypt the link, then using LESC serves no purpose as it is just a way to generate the key based on a shared secret. So it seems you can get the behaviour you want by simply not supporting LESC on the nRF side. Enabling LESC but not wanting to generate a shared secret and encrypt the link makes little sense.

    Regarding how to know if bonding or not, you get that with the BLE_GAP_EVT_AUTH_STATUS event. (You configure if the nRF should support bonding or just pairing by setting the bond field in the ble_gap_sec_params_t instance you pass to pm_sec_params_set() accordingly.)

    Einar

  • Hi Einar,

    It is an odd use case but the use case is just wanting to get the IRK from a device, if both devices support LESC then they will establish an LESC encryption so that they can exchange their IRKs (as an encrypted link is required to exchange the IRK), if one side doesn't then it will still establish encryption to exchange the keys (which is working as intended, own and peer enc is set to 0). So the full details are both devices want to bond by exchanging IRKs but do not want to store encryption keys (they should just be temporary for the duration of the connection) - so the bond flag is required because the IRKs are going to be stored but the problem is in the BLE_GAP_EVT_AUTH_STATUS event, how do you know (if it's an LESC bond) if you should be storing just the IRK in the bond database or if the encryption details should be stored as well? That is the issue I am trying to resolve.

    Thanks,
    Jamie

  • Hi Jamie,

    I see. Then I do not see any way around bonding as normal, and then removing the bond later, while keeping the IRK (for whitelisting or whatever you are using it for). On the nRF side that should not be a problem, though there are no examples doing that. I don't know if it will be possible on iOS and Android, though.

Reply Children
No Data
Related