This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Legacy Pairing/Bonding problem, pc-ble-driver, NRF52, central

I currently need to solve pairing/bonding to be able to implement DFU with the buttonless bonded bootloader. So I need to handle bonding/pairing from my central device, controlled using pc-ble-driver (and connectivity firmware SD 140, v6.1.1). The project is at a late stage. Scanning, connecting, discovering and using characteristics is already really stable and works as expected.

Just a side note: The peripheral firmware seems to be correct, as I'm able to do DFU from a mobile application running on Android!

What already works:
After a connection to an unbonded peripheral is established (just before discovering services), I call sd_ble_gap_authenticate() with:

const ble_gap_sec_params_t SecurityParams = {
1, // Bond
0,
0,
0,
BLE_GAP_IO_CAPS_NONE,
0,
7,
16,
{ 1, 1, 0, 0 },
{ 1, 1, 0, 0 }
};

which responds with BLE_GAP_EVT_SEC_PARAMS_REQUEST. I answer this by calling sd_ble_gap_sec_params_reply(sec_status=0, p_sec_params=NULL, keySet), where keySet is just an empty buffer. This call fills the own/p_id_key with key data, which I store in a file. I than got BLE_GAP_EVT_AUTH_STATUS with bonded=true and auth_status=0 (SUCCESS).

At this point, I'm able to subscribe to BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID's indication, so I assume bonding was successful. I can repeat this by resetting the bonding information in the peripheral.

What does not work:
I'm not able to recreate this state if the peripheral holds the bonding information. After the connection has been established I directly got BLE_GAP_EVT_SEC_REQUEST. Upon receiving this event, I call sd_ble_gap_authenticate() using the parameters above (tested with bond=0 and bond=1). I've also tested calling sd_ble_gap_authenticate() a second time after handling BLE_GAP_EVT_SEC_REQUEST. Either case, I always receive BLE_GAP_EVT_AUTH_STATUS with bonded=false and auth_status=133 (BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP). So I neither got BLE_GAP_EVT_SEC_PARAMS_REQUEST to supply my stored keys to the central.

I've tried to understand how pc-nrfutil handles this, but looking into github.com/.../dfu_transport_ble.py , def bond(), seems to do it this way too. I've no idea what I do wrong.

What's the correct way to connect / pair / (reestablish-)bond to an already bonded peripheral?

A second question: Does the connectivity firmware store the bonding keys on device site too? This question is centered about the usability. If I connect my central device to a different host PC and try to connect to an already bonded peripheral, does the central know the bonding keys (e.g. stored in flash) or do I have to copy my host site keystore to the new host (and supply them when receiving BLE_GAP_EVT_SEC_REQUEST)?

Many thanks,
Thomas

Parents
  • Hello Thomas,

    The peer manager on the peripheral will by default reject bonding requests from a previously bonded peer, so this is likely why you get the BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP status in response to your request. I explained how you can configure the Peer manager to accept bond updates in my post here: https://devzone.nordicsemi.com/f/nordic-q-a/51965/pairing-and-bonding-after-deleting-synchronization/208927#208927. The other option is to delete the bond on the DFU target before you initiate DFU.

    A second question: Does the connectivity firmware store the bonding keys on device site too? This question is centered about the usability. If I connect my central device to a different host PC and try to connect to an already bonded peripheral, does the central know the bonding keys (e.g. stored in flash) or do I have to copy my host site keystore to the new host (and supply them when receiving BLE_GAP_EVT_SEC_REQUEST)?

    The host (pc-ble-driver app in this case) is responsible for the key storage. The connectivity FW does not store anything to flash.

    If anything is unclear, let me know.

    Best regards,

    Vidar

  • I've sniffed both the initial bond and the reconnect case. When doing the initial bond, data is encrypted when I start to discover services (after calling sd_ble_gap_authenticate()), while in the reconnect case, the discovery part is unencrypted (as you mention).

    The image below shows the section when I try to reconect. If I understand correctly, LL_ENC_REQ is triggered by the call to sd_ble_encrypt(). Comparing the information from VS debugger with the sniffed data, the master id is sent correctly (red arrows).

    Following the response from the peripheral (LL_ENC_RSP).

    For completeness, finally the log from the previous bonding:

    I'm not sure if this is helpful.

    Anyway, if the key that I use calling sd_ble_encrypt() would be corrupt, wouldn't this not totally fail? As said, I still got security_mode=1, level=1 from BLE_GAP_EVT_CONN_SEC_UPDATE. I expect this wouldn't be the case using a corrupted key.

  • Hm, does all packets following encryption start in the first connection and subsequent connections have the wrong mic? The sniffer should be able to decrypt the packets when using legacy pairing: Sniffing a connection between bonded devices

    Are you able to to upload the sniffer file here?

  • ws-sniffs.7z

    Of course. These are the sniffs used in the screenshots above.

Reply Children
No Data
Related