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

How to setup pre-bonded link / pairing at factory time

I have some Bluetooth LE v4.2 beacons that I will connect ONLY with known devices that we may call "readers". No consumer with use my beacons, I program them, I install them, I consume the data and I sell the service.

I want to use Bluetooth LE Secure Connections, but replace the pairing by a hard-coded shared secret. My primary concern is that only known, authenticated device can send data with integrity protection.

I understand that I probably only need the CSRK, but I am not sure if I should still generate a LTK and how the CSRK is generated.

So far, I thought about :

  1. Skip pairing and use my shared secret directly as the CSRK for all my devices.
  2. Skip pairing and use my shared secret directly as the LTK for all my devices. Then generate a random CSRK that I share through the link.
  3. Skip pairing phase 1, 2 and use my shared secret to generate a device specific CSRK without the random numbers, almost like the usual phase 3 LTK generation, but for CSRK.
  4. Skip pairing phase 1, 2 and use my shared secret to generate a device specific LTK without the random numbers, almost like the usual phase 3 LTK generation. then generate a random CSRK that I share through the link.

What would be my best option ?

A few previsions :

  • We are talking about 1000s of devices, and more will join the network every day.
  • I am already doing advertisement filter, etc. I only connect to devices with my vendor id.
  • Replacement is preferable to any kind of lack of security in the authentication, my added value is the trust in data.
  • I have an OTA update system for all the devices.
  • Here is what I currently planning to do. Thanks Emil Lenngren !

    Pre-shared key

    If you remove the pairing step from BLE security you basically just have AES-CCM with pre-shared keys, where each connection has an own key derived from the shared key and a nonce from each side. LESC is about the pairing step which you want to remove, so that doesn't apply in that case.

    If you use pre shared keys and want a dynamic setup where you must be able to add nodes without the need to update the key set for all devices already manufactured, you must have an algorithm that for example derives a key for use between two nodes based on for example a master key and the Bluetooth device addresses (if the master key is leaked, you're screwed), or some key server node.

    A master key will be included in the new FW release code (that's probably my major weakness, but I cannot do much about it). The Long Term Key, used for communication encryption, will be derivated from the master key using generation function fc (inspired by the f5 function described in the Bluetooth specification).

    The definition of this key generation function fc makes use of the MAC function AES-CMACT with a 128-bit key T.

    The input of the function are:

    • M is 128 bits
    • A1 is 56 bits
    • A2 is 56 bits

    The string “******” is mapped into keyID using extended ASCII as follows:

    • keyID = 0xXXXXXXXXXXXX

    The output of the key generation function fc is as follows:

    • fc(M, A1, A2) = AES-CMACM(keyID || 0x00 || A1 || A2 || Length = 128)

    The LTK is calculated as:

    • LTK = fc(Master key, DB_ADDR_master, DB_ADDR_slave)

    CSRK

    Forget about CSRK. It's a bad idea that almost no BLE stacks support.

    Generate and store keys

    The generation of the key shall happen on-the-fly when the connection is established. The keys are stored for the next communication to lower the CPU consumption.

    Master key leak

    To prevent OTA process to be used if the key is leaked, and allow corrective measure to be pushed safely, the new version of OTA system will include a FW signature system using public/private key.

    Of course, I will try to obfuscate the key in my code, but I am still not sure how to do it. Also I could not find any memory with programmer write only rights, so I am forced to include the key in my code (if someone has a solution for that).

    A common solution for these kinds of issues is to use asymmetric keys. Each device has a private/public key pair signed by your "certificate authority" (which really is just a "master" keypair you should avoid to leak at all costs). To create session keys, just use ECDH and sign the ephemeral public keys with the burnt in private keys. If a private key is leaked, only that device is compromised.

    I couldn't find out how I could archive keypair signature without having to request the central certification authority (the one with the master private key) for each public key. If someone have something more practical, so that I could understand.

    Device ID spoofing if the FW is leaked

    During programming, use an external authority server (that has a list of all devices in production) to sign the deviceid using its private key. Include public key and signed deviceid in FW and add auto-check during first boot.

    This will prevent an attacker with the FW to spoof deviceid without physical access, but cannot prevent physical attack to read the signed deviceid since (again) I could not find memory with programmer write only rights.

Related