Implementing Eddystone EID (and AES) on the nRF52805

Hello, I'm in the process of attempting to implement Eddystone EID on the nRF52805.

It's been a bit of a nightmare, so I'm finally taking the bold step to make my first forum post!

The current sample for eddystone doesn't have any EID implementations yet... It's under 'TODO'

Here is all the documentation from Google:

 https://github.com/google/eddystone/tree/master/configuration-service

https://github.com/nrfconnect/sdk-zephyr/tree/main/samples/bluetooth/eddystone#id1

For now, I'm stuck on even just figuring out how to encrypt the beacons UUID and get the EID.

Please help Slight smile

Parents
  • Hi,

    The Eddystone sample in nRF Connect SDK (Zephyr) is very basic, and at the same time a full Eddystone beacon is quite complex. This is included in the nRF5 SDK though (Eddystone Beacon Application), so I suggest you consider that if you need it. May I ask why you are interested in Eddysone, seen as it is no longer maintained and Google discontinued support for it in 2018?

  • Hi, thank you for the response!

    I've been trying to understand that example for the past few days.

    I'm attempting to use Eddystone's EID as a convenient way to change my beacon's MAC address to prevent tracking, while still retaining the identity when the MAC address is decrypted. I suppose it doesn't actually have to be Eddystone, I'm just trying to use the existing framework to simplify what I'm trying to do.

  • Great! I've got it complied and running.

    Is there a command or function I need to call to get the IRK key?

    I'd like to get the IRK key, then transmit it over UART to the other BLE device.

    *I'm asking this because I'm assuming that the IRK handling doesn't just happen automatically.

  • Hi,

    IRK handling is automatic in the sense that if you enable privacy (CONFIG_BT_PRIVACY=y), it is automatically generated and used by the stack. However, there are API functions you can use to mage identities (the bt_id_* functions). The simplest way here is perhaps to use bt_id_create(). Depending on the parameters, it will generate an IRK for you (and populate a buffer with it so that you can do with it what you need), or use an IRK you provide. See the API doc for more details.

  • I tried to make a few identities, but I think my issue lies in the parameters I call.

    I'm trying to enable RPA, but there is no BT_LE_ADV_PARAM that exists by default for it.

    I've tried to create my own, and put this in the main.c file:

    	#define BT_LE_ADV_PARAM(_options, _int_min, _int_max, _peer) \
    				((struct bt_le_adv_param[]) { \
    					BT_LE_ADV_PARAM_INIT(_options, _int_min, _int_max, _peer) \
    				})
    
    
    
    				#define BT_LE_ADV_NCONN_DIR_RPA(_peer) BT_LE_ADV_PARAM(BT_LE_ADV_OPT_DIR_ADDR_RPA, \
    						0, 0,\
    						  _peer)

    But it seems to freeze and doesn't give me an error or success message when I start BLE with:

    bt_le_adv_start(BT_LE_ADV_NCONN_DIR_RPA(peer), ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));

    The devices successfully connect when I start with:

        err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    My current approach has nrf be connectable with a random address [This part works], then send over the IRK information with UART [Struggling with this]. Next, it disconnects, stops broadcasting, and changes to a non-connectable random resolvable address.[not working]
    Something I've also noticed is that the IRK is said to be 16 bytes, but the pointer is only a uint8_t. How do I fit all that data in there?
  • Hi,

    adojang said:
    I'm trying to enable RPA, but there is no BT_LE_ADV_PARAM that exists by default for it.

    You do not need any specific configuration of the advertiser, just enable privacy. The simplest is to take the beacon example and add "CONFIG_BT_PRIVACY=y". Then you will see that it advertises with a RPA. If you also set CONFIG_BT_RPA_TIMEOUT to a low value you can easily that the address changes every interval.

    adojang said:
    Something I've also noticed is that the IRK is said to be 16 bytes, but the pointer is only a uint8_t. How do I fit all that data in there?

    This is a pointer to an array of uint8_t. Generally in C programming, arrays are passed around as pointers to the first element. So this is how it is done in all APIs that handle arrays.

  • Thank you once again, I've learned a lot!

    I'm having trouble establishing a connection from my client (ESP32) to my peripheral (NRF) when enabling privacy. Without privacy, the uart example works great, and I can exchange information.

    My current approach is going to be to connect to the NRF while it has a non-private address, exchange the IRK key over UART, then switch the NRF device to it's privacy enabled mode, setup a new identity with that specific IRK key, and start advertising.

    On my client side, I'd like to generate a large whitelist of MAC addresses using the IRK, but I haven't been able to find the low level mathematical implementation of how to convert the IRK to a mac address. Could you point me to a resource?

Reply
  • Thank you once again, I've learned a lot!

    I'm having trouble establishing a connection from my client (ESP32) to my peripheral (NRF) when enabling privacy. Without privacy, the uart example works great, and I can exchange information.

    My current approach is going to be to connect to the NRF while it has a non-private address, exchange the IRK key over UART, then switch the NRF device to it's privacy enabled mode, setup a new identity with that specific IRK key, and start advertising.

    On my client side, I'd like to generate a large whitelist of MAC addresses using the IRK, but I haven't been able to find the low level mathematical implementation of how to convert the IRK to a mac address. Could you point me to a resource?

Children
  • To the math you can refer to BT core spec 5.3 page 1559 and page 3085. There are references there for digging further down. Note that this is not normally something you would need to do, as any Bluetooth stack out there should be capable of it. I cannot say how this is with Espressif so you would need to ask them for details about their devices. I would expect that they provide some tools for whitelisting IRKs though, as this is an essential feature.

  • Thanks for all the help Einar!

    I'm still struggling with the following portions:

    -IRK Generation (I'm still a little uncertain how to use pointers to create it)

    -Creating, and USING an identity with advertising.

    After the IRK key has been exchanged, the NRF will completely disconnect, and change its ble parameters. Specifically using BT_LE_ADV_NCONN [Non-connectable advertising with private address]

    I assume this allows for address resolution?

    The ESP32 will then scan, and when it finds a mac address from the correct manufacturer (I'll filter them a bit) it will do the math to confirm if the address resolves using the IRK.

  • adojang said:
    -IRK Generation (I'm still a little uncertain how to use pointers to create it)

    That is done by the bt_id_create() function. For instance, to generate an IRK you need to provide an array that is all 0. Something like this (just typing now so there may be typos but the principle should be correct):

    bt_addr_le_t addr; // set to someting sensible, refer to samples
    uint8_t my_irk[16] = {0};
    err = bt_id_create(&addr, my_irk)

    Here you provide an empty IRK buffer, so when the bt_id_create() function returns, the new IRK is written to the buffer an you can send it to the peer. Also, the identity (including IRK) is stored in flash of the nRF for later use, so you do not need to keep track of it yourself after exchanging with the peer. Refer to the bt_id_crate() API doc for details.

    adojang said:

    USING an identity with advertising.

    After the IRK key has been exchanged, the NRF will completely disconnect, and change its ble parameters. Specifically using BT_LE_ADV_NCONN [Non-connectable advertising with private address]

    when starting to advertise you can use BT_LE_ADV_NCONN, yes. Then, as long as privacy is configured, that will be used (with the configured identity).

Related