Pairing, Bonding, and Resolvable Private Address

I’m at the tail end of my project, and I’m turning my focus to the pairing/bonding issue.

 The project includes a Central/Client device that connects to several Peripheral/Server devices.  The Peripheral unit advertises its serial number and the Central initiates connection upon detecting a Peripheral with a serial number on an “approved device” list (“whitelist”).  Once connected, they stay connected unless the user takes the serial number off the “approved device” list or the RF signal is temporarily lost, in which case the connection will be immediately reestablished upon detecting the restarted advertising.

 The only security concern the customer has is that a hostile agent doesn’t advertise with an approved serial number, get connected, and provide bogus data.  However, when a Peripheral is added to the “approved device” list, it is part of a process in which a human operator has installed the Peripheral with the known serial number in the vicinity, so the user knows the device is expected and verifies that it connects.  If there were a hostile agent advertising with the same serial number, the user would be informed.  The concern is that the hostile agent would substitute the false device for a real, already connected device.

 Our thought is that using Resolvable Private Addresses gets us past this concern.  Once connected under controlled, supervised conditions, a Peripheral must always be the same device with the IRK negotiated during the connection process.  While the devices stay powered for their entire lifetime, it is possible that the mains-powered Central could be cycled, so storing the IRK in flash NVM is good.  There won’t be much coming-and-going, so using the flash on both sides is not a concern.

 I believe this approach does not require additional authentication.  The data on the link is not interesting (room temperature, humidity), so there is no need for encryption.  So, in terms of security, BT_SECURITY_L1.

 I’ve got CONFIG_BT_SMP and CONFIG_BT_PRIVACY enabled on both sides.  I verify with nRF Connect for Desktop that the Peripheral is advertising with a RPA (or “RandomPrivateResolvable”, as nRF Connect reports it).  I would have expected some event about resolving the address, either by nRF Connect or by the Central reporting the occurrence of a identity_resolved() callback, but I don’t see that.

 (In fact, after connecting to the Peripheral, at every point where nRF Connect refers to the Peripheral, it uses the same address it saw during advertising.  Is resolution actually occurring?  I figured it would be done automatically after sensing that the address was a RPA.)

 I’m a bit fuzzy on connecting/pairing/bonding.  Under nRF Connect I can pair the newly-connected Peripheral without clicking any of the boxes under authentication and pairing appears to succeed with the message “Security updated, mode: 1, level: 2” (why is it level 2?).  If I reset the device and reconnect to it, I have to do the pairing again to get the message, so apparently pairing is just for the security update and not for remembering the IRK for resolving the address.  I guess that’s the bonding part.

 Following the pattern in the bluetooth/peripheral sample, I add the following to prj.conf:

CONFIG_FLASH=y

CONFIG_FLASH_MAP=y

CONFIG_FLASH_PAGE_LAYOUT=y

CONFIG_NVS=y

CONFIG_SETTINGS=y

CONFIG_BT_SETTINGS=y

 and put “settings_load()” after the bt_enable() call.  I also put some code to display all the bond info at reset using “bt_foreach_bond()”.  When I click the “Bond” box under “Pair” in nrf Connect, it says “Storing bond info for device <address>”.

 (When I try to instrument the pair process using “bt_conn_auth_cb_register()” to set up a “pairing_complete()” callback, the device resets upon pairing.  I’m guessing this authentication callback provision is only useful when doing authentication via a passkey or OOB or whatever, but I wasn’t expecting it to crash.)

 At this point, I reset the device.  After coming back up, it reports a stored bond with the nRF Connect device.  I would expect that upon connecting, nRF Connect (the Central) would look through the bond info it has for an IRK that resolves the RPA of the device and pair automatically.  No message about changing the security level.  I proceed to pair anyways and get an error 4 (BT_SECURITY_ERR_AUTH_REQUIREMENT).

 Using nRF Connect SDK 2.1.0.  What am I missing?

Parents
  • Hi,

    I suggest you backtrack a bit and revise your strategy. As I understand it, the data is always sent in a connection (not advertised). You also write that you want to prevent and attacker from sending bogus data, but you do not need encryption. However, I do not see a need to explicitly avoid encryption. You are thinking to use random resolvable address as a way to detect if the peer is the same as before (as it has to have the right IRK). That does not seem sound sound, and I would suggest using the standard Bluetooth approach instead of using mechanisms for other purposes than intended, hoping you did not get anything wrong. Privacy (random resolvable addresses) is only intended to be used to prevent tracking. Regarding why this is not sound, an attacker could still spoof the address (the address change regularly but not often, perhaps every 15 minutes, and he could also jump right into a connection. A key point about encryption is that it does not only protect the data from being visible, but it also provide authenticity, which you want.

    The only standard way to obtain the IRK is to do bonding, so you would need to do that anyway. And that is also why your link gets level 2, which means unauthenticated encrypted link. Unauthenticated here is because you do not use any man in the middle protection mechanisms here (like passkey entry or numeric comparison). In any case, that means you already have an encrypted link. Then it would be enough to require that a pair you are already bonded to will not be allowed to re-pair (meaning if the peer lost bonding information either because it really did or an attacker is spoofing it, the link will be disconnected as it cannot be encrypted).

    So, unless I misunderstood something, the simplest and most secure (as you are using well though out standard approaches in stead of devising your own), would be to forget about resolvable addresses and just use encryption and require level 2 for your characteristics, and you are ready to go.

Reply
  • Hi,

    I suggest you backtrack a bit and revise your strategy. As I understand it, the data is always sent in a connection (not advertised). You also write that you want to prevent and attacker from sending bogus data, but you do not need encryption. However, I do not see a need to explicitly avoid encryption. You are thinking to use random resolvable address as a way to detect if the peer is the same as before (as it has to have the right IRK). That does not seem sound sound, and I would suggest using the standard Bluetooth approach instead of using mechanisms for other purposes than intended, hoping you did not get anything wrong. Privacy (random resolvable addresses) is only intended to be used to prevent tracking. Regarding why this is not sound, an attacker could still spoof the address (the address change regularly but not often, perhaps every 15 minutes, and he could also jump right into a connection. A key point about encryption is that it does not only protect the data from being visible, but it also provide authenticity, which you want.

    The only standard way to obtain the IRK is to do bonding, so you would need to do that anyway. And that is also why your link gets level 2, which means unauthenticated encrypted link. Unauthenticated here is because you do not use any man in the middle protection mechanisms here (like passkey entry or numeric comparison). In any case, that means you already have an encrypted link. Then it would be enough to require that a pair you are already bonded to will not be allowed to re-pair (meaning if the peer lost bonding information either because it really did or an attacker is spoofing it, the link will be disconnected as it cannot be encrypted).

    So, unless I misunderstood something, the simplest and most secure (as you are using well though out standard approaches in stead of devising your own), would be to forget about resolvable addresses and just use encryption and require level 2 for your characteristics, and you are ready to go.

Children
  • Thank you, Einar, for setting me straight on the right way to do things.  I took out the "CONFIG_BT_PRIVACY" from prj.conf and things work as expected.

    With RPA:

    • "CONFIG_BT_PRIVACY=y" present in prj.conf
    • Bond info erased (freshly programmed, bulk erase, does not report any bond info present at boot)
    • nRF Connect sees address as "RandomPrivateResolvable"
    • Connects fine.
    • Upon "Pair", with "Perform bonding" box checked, succeeds; both sides report security updated to level 2 (no auth, link encrypted), and nRF Connect says "Storing bond info for device <address>", where address is the same address picked up from the advertising
    • Reset Peripheral. Peripheral reports the presence of bond info at boot. When advertising detected at nRF Connect, connect. No report of security update. Pairing (with/without bonding) fails with error 4 (BT_SECURITY_ERR_AUTH_REQUIREMENT)

    * Unexpected behavior *

    Without RPA:

    • Removed "CONFIG_BT_PRIVACY=y" from prj.conf
    • Bond info erased (freshly programmed, bulk erase, does not report any bond info present at boot)
    • nRF Connect sees address as "RandomStatic"
    • Connects fine.
    • Upon "Pair", with "Perform bonding" box checked, succeeds; both sides report security updated to level 2 (no auth, link encrypted), and nRF Connect says "Storing bond info for device <address>", where address is the same address picked up from the advertising
    • Reset Peripheral. Peripheral reports the presence of bond info at boot. When advertising detected at nRF Connect, connect. Both sides report security updated to level 2.

    * Expected behavior - automatic security update *

    Questions:

    1. Why does automatic repairing not work for RPA like it does for Random Static?
    2. I've got a "identity_resolved()" callback, but it is not being called. Is the sharing of IRK and use for resolving RPA actually happening?

    I know I'm not using RPA anymore at this point, but I don't understand what I'm seeing and suspect there's something more required than just "CONFIG_BT_PRIVACY".

    Also: I'm picking up (based on seeing a "BLE_GAP_SEC_STATUS_AUTH_REQ" error) that nRF Connect is built under nRF SDK (has not been updated to NCS).  nRF Connect has a checkbox for "Perform bonding" that allows pairing (upgrade the security) to be commanded without bonding (committing the pairing info to persistent memory).  Some additional questions related to pairing/bonding:

    4.  nRF Connect separately reports pairing ("Security updated, mode: x, level: y") and bonding ("Storing bond info for device <address>").  Zephyr has a means of reporting pairing results via the security_changed() callback but I don't see how to get bonding results or even that bonding occurred.  Can some technique be used to do this? Registering a "pairing_complete()" callback via "bt_conn_auth_info_cb_register()" causes the Peripheral to reset upon connection (this feels like a bug).  I guess calling "bt_foreach_bond()" at some delay after "security_changed()" and looking for the address in the callback might work, but that seems a bit clunky.

    5. Looking through the Connection Management docs, it looks like pairing implies bonding. There's only "bt_conn_set_security()".  However,  nRF Connect allows this.  But it looks like bt_set_bondable() will do this.  It works, but is that the intended use?

  • Hi,

    IRKs are only exchanged when bonding (not when pairing without bonding), and not necessarily when neither of the peers use privacy (RPA). When not using privacy in any peers, you will not get any identity_resolved callbacks, because there is nothing to resolve.

    You are right that nRF Connect for Dekstop Bluetooth use firmware on the nRF that is based on (a quite old) SoftDevice and nRF5 SDK version.

    Using the pairing_complete callback is the right way to see if bonding occured (and not just pairing). I cannot say based on what you write what happended in your case, but this should normally work and if you search for "pairing_complete" it in the nRF Connect SDK you can see many examples of it being used.

    Pairing does not imply bonding in the sense that there is no problem to pair without bonding. But normally this is something you don't want to change dynamically, and there are some configuration parameters that can be adjusted for this. For instance CONFIG_BT_BONDABLE  (which you don't see that much as it defaults to y), and CONFIG_BT_BONDING_REQUIRED which enforces bonding.

    The function bt_set_bondable() is only if you want to change dynamically between bonding and pairing. As stated in the API doc: "For the vast majority of applications calling this function shouldn't be needed.". But if your use case is one of the few where it makes sense to sometimes bond and sometimes pair, then this is what you want to use.

  • Just to finish this off:

    Is the nRF Connect for Desktop not configured to handle Privacy?  My Peripheral was definitely set up for RPA, and nRF Connect was recognizing a "RandomPrivateResolvable" address type, but the expected behavior for identity resolution or even security elevation during bonding was not occurring.

    Well, I see one use of pairing_complete in the Zephyr Bluetooth samples, namely peripheral_sc_only, and more generally of the bt_conn_auth_info_cb structure of which pairing_complete is a member, and that project does passkey authentication.  So I figured the callbacks of the bt_conn_auth_info_cb would only work if authentication was being performed, which my project was not doing.  Didn't surprise me.  But the system crashing did.

  • Hi,

    It should be able to do identity resolution, but only after bonding (not just pairing). I am not sure about the link to authentication here, but perhaps the problem is that you have not configured nRF Connect for Desktop Bluetooth to do bonding and with full I/O capabilities? See Pairing devices for details about that. (Not that it is related to privacy, though, so perhaps you are asking about two different things?).

Related