Using different peer manager settings for each role in a multi-role (central and peripheral) device.

Hello,

We have a device that acts as both a bluetooth central and a peripheral. The device does not actually have a display or a keyboard, but it has another input port that fills the role of the keyboard. When acting as a central device, we support passkey pairing by using this other (secure) port to supply the passkey.

The trouble is that we ALSO want to be able to support static passkey pairing for the bluetooth peripheral. Because it is a static passkey, we do not actually need to show it on a display for the peripheral to know what it is.

To get the central device to work, we need to tell the peer manager that we have a keyboard

#define SEC_PARAM_IO_CAPABILITIES   BLE_GAP_IO_CAPS_KEYBOARD_ONLY               

To get the peripheral to use our passkey pairing, we need to tell the peer manager that we ONLY have a display.

#define SEC_PARAM_IO_CAPABILITIES   BLE_GAP_IO_CAPS_DISPLAY_ONLY                

If we try to tell it that we have both a keyboard and a display it seems to act the same way that it acts if we say that it only has a keyboard. When we try to pair from a phone the phone generates the passkey and asks our device to enter it. Our device does not actually get an event to enter a key though. Even if it did, we want it to use our static passkey, not the one generated on the phone. For this test we used the nrf connect app as the central.

Is it possible to run two instances of the peer manager with different settings? One for the central device and one for the peripheral? If so, how would it know when events to handle?

Should we somehow de-initialize and re-initialize the peer manager when we get a peripheral connection? It seems like the peer manager needs to be initialized before the connection, which would make this difficult.

Is there a single configuration that we have overlooked that would be flexible to solve both of our problems?

Should we be trying to fix this on the phone app side? 

Is this just not possible?

this device using SDK version 15.2, softdevice S132

Edit: please note that this question is not about static passkey pairing. It is about supporting different peer manager settings for different roles.

Thanks!

Parents
  • Static passkeys aren't really supported by the BLE standard.

    If you try to do it that way anyway, please note that the security is severly affected compared to using a new random passkey per attempt: a passive eavesdropper always learns the passkey used after a successful attempt. It can also be brute forced in at most 20 attempts since you always learn at least one bit of the passkey which was incorrect. See insinuator.net/.../.

  • Hi Emil, yes, yes. thanks. I should have pre-empted this in my question. First of all, it isn't that bluetooth does not support static passkeys, they just didn't implement it well. My understanding is that the statement about discouraging static passkeys did not appear until 5.1, but the vulnerability was introduced in 4.2, so it is incorrect (or at least very generous) to say that they don't support it. Notably, that screwup only affects passkey pairing if you have LESC enabled, which is yet another reason why someone might want different peer manager settings for a peripheral vs a central.

    However, there are also other ways to fix this limitation of the ble pairing system. For example, instead of using a static passkey directly, you can use the static token pre-shared between the two devices along with a value that changes on each connection to derive (via a 1 way algorithm) the actual static passkey and then change the static passkey per connection. As long as the peer can get or predict the changing value it can derive the new passkey. You still get all the normal benefits of LESC and passkey pairing, you still don't need a display because the base token can be pre-shared, and it cannot be brute forced in 20 attempts because the actual passkey value changes on each connection attempt. You can also use a longer token if you like.

    There are other possible solutions. I do appreciate that you are trying to keep people from making security mistakes, but my question is very notably not about how to address the limitations of the bluetooth passkey validation algorithm. My question was about supporting different peer manager settings for the different roles in a multi-role system.

    If you have any information on that, I would very much appreciate it.

  • The relatively new "statement about discouraging static passkeys" is actually not anything that functionally changes the specification compared to previous versions. It is just an additional explicit warning text that was added that explains that using a static passkey compromises the security (even though doing so is not one of the allowed options).

    The original Bluetooth 4.2 spec simply states that in step 1, passkey is "generated and displayed on one device, and the user then inputs it into the other (step 2)". As it is generated in step 1, it can obviously not be a previously created static passkey or be reused in the next attempt. The section about random numbers says that random numbers are used e.g. for "Passkeys used in authentication", including the security requirements and tests a random number generator must pass.

    Also when looking at the I/O capabilities, it should be pretty obvious that a static passkey is not supported, since there is no I/O capabilitiy called "label containing a static passkey" or similar. Faking "display" when the device doesn't have a display should make it obvious that you're doing something not supported.

    Creating the passkey using some cryptographic hash based on some fixed value and some variable value seems to me to be secure, assuming a third party cannot derive the same passkey. However, not doing what the spec says, even though it might be technically possible, makes your product violate the standard and I'm not sure if you are allowed to certify such a Bluetooth device with Bluetooth SIG, although I'm no expert here. Note that the one of the big points of certifying and qualifying Bluetooth products is to make sure that different devices are interoperable with each other, even if they are made by different manufacturers.

    Note that Legacy Passkey pairing is even worse as it can be cracked in only one pairing attempt, since the protocol has a serious flaw that was not discovered in time before the spec was released. See https://eprint.iacr.org/2013/309. This vulnerability is mainly an issue when it is the initiator that displays the passkey. In other cases, Legacy Passkey pairing is in general insecure because it allows for MITM and eavesdrop attackers.

    Applications that want to use a static passkey for secure connectivity use a Password-authenticated key exchange (PAKE) like SPAKE2+ on top of unencrypted Bluetooth at the application layer. This is e.g. how the Homekit and Matter smart home protocols achieve secure connectivity. These protocols do not use the security mechanisms present in the Bluetooth standard, most likely since it does not support any secure methods using static passkeys.

    Back to your original question, it is possible to use different security parameters every time. When acting as a central, simply call pm_sec_params_set with your desired properties right before calling pm_conn_secure. When acting as a peripheral, implement the peer manager event handler per the documentation and listen for the PM_EVT_CONN_SEC_PARAMS_REQ event. When this event is received, call pm_conn_sec_params_reply with the desired properties.

  • Hi Emil, This is helpful. Thanks.

    For anyone reading that just wants the answer

    Back to your original question, it is possible to use different security parameters every time. When acting as a central, simply call pm_sec_params_set with your desired properties right before calling pm_conn_secure. When acting as a peripheral, implement the peer manager event handler per the documentation and listen for the PM_EVT_CONN_SEC_PARAMS_REQ event. When this event is received, call pm_conn_sec_params_reply with the desired properties.

    we'll give that a shot!

    Using encryption at the application level for the peripheral is a good option too, but if you already need to support LESC for the central it is simpler and a better use of system resources to re-use the existing system instead of adding another one. Using the existing system is also better for interoperability. 

    Creating the passkey using some cryptographic hash based on some fixed value and some variable value seems to me to be secure, assuming a third party cannot derive the same passkey. However, not doing what the spec says, even though it might be technically possible, makes your product violate the standard and I'm not sure if you are allowed to certify such a Bluetooth device with Bluetooth SIG, although I'm no expert here. Note that the one of the big points of certifying and qualifying Bluetooth products is to make sure that different devices are interoperable with each other, even if they are made by different manufacturers.

    I think that the approach that I outline does do what the spec says. The section that you quoted seems relevant.

    "generated and displayed on one device, and the user then inputs it into the other (step 2)".

    You can feel free to correct me if I am wrong (I would actually appreciate it, but you have already helped enough so don't feel obligated), but I don't think the spec specifies approved methods for generating a passkey. hashing a pre-shared token with a changing value to generate a passkey does generate a passkey. I don't actually know how the SDK generates its passkeys, but the approach I outlined should be comparably strong to generating a random number. Depending on how the random number generator is implemented, it might be better (as long as the pre shared token is device specific and stays secret). 

    "Static" here would really just mean that this approach would not be using the SDK/softdevice/whatever normally does it to generate the passkey.

    I am actually not sure that I agree that a truly static passkey would not count as generated - especially if it is a device specific value. If it was generated once, then it was generated. I don't think the 4.2 spec says that it needs to be generated on every attempt. I agree that this is NOT good practice, but I am not as willing as you are to say that truly static passkeys were never an intended use case of the 4.2 spec.

    From another angle, The spec does say

    "The Passkey Entry association model is primarily designed for the scenario
    where one device has input capability but does not have the capability to
    display six digits and the other device has output capabilities"

    So maybe based on that you could argue that any other use of the system is outside the spec, but this doesn't read as a requirement to me. It is just a statement about their design intent.

    Overall, I think that permissive specs are better than unnecessarily restrictive specs, so I guess I should not be too critical of them for arguably supporting a use case that turned out to not work well.

    Thanks again.

  • In the same spirit, you have this one too ;)

    https://xkcd.com/221/

    The same section in the spec says the used passkey is gradually disclosed and the first wrongly guessed bit is leaked in every attempt, as well as that a brute forcer has 0.000001 success of probability. So the intention must have been that passkeys should not be reused, since reading this section with the assumption that the passkey is fixed and reused does not make any sense. In any case, the spec has now been clarified since it was apparently not clear enough before.

Reply
  • In the same spirit, you have this one too ;)

    https://xkcd.com/221/

    The same section in the spec says the used passkey is gradually disclosed and the first wrongly guessed bit is leaked in every attempt, as well as that a brute forcer has 0.000001 success of probability. So the intention must have been that passkeys should not be reused, since reading this section with the assumption that the passkey is fixed and reused does not make any sense. In any case, the spec has now been clarified since it was apparently not clear enough before.

Children
No Data
Related