Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All ESP32 Nimble peripherals have the same IRK when using RPA? #539

Open
jangellx opened this issue May 3, 2023 · 8 comments
Open

All ESP32 Nimble peripherals have the same IRK when using RPA? #539

jangellx opened this issue May 3, 2023 · 8 comments

Comments

@jangellx
Copy link

jangellx commented May 3, 2023

I've hit a problem where I am trying to have an iPhone connect to multiple ESP32 NimBLE devices acting as peripherals using RPA and encryption. All ESP32s are running the same Arduino sketch.

This is the authentication I'm using on the ESP32:

NimBLEDevice::setSecurityAuth(  true, true, true);		 // Bonding, man-in-the-middle protection, secure connection pairing
NimBLEDevice::setSecurityIOCap( BLE_HS_IO_DISPLAY_ONLY );	 // We have a display for the passcode
NimBLEDevice::setOwnAddrType(   BLE_OWN_ADDR_RANDOM, false );	 // Random Private Address support, as required for iPhone bonding

I've found that the iPhone can connect and bond to the first device, and everything works. I can then bond to the second ESP32, and everything works. They both work as long as the iPhone remains connected.

The problem comes when I disconnect and try to reconnect. I can only connect to the most recently bonded ESP32. Attempting to reconnect to the first bonded ESP32 fails with an authentication error. If I boot up a third ESP32, the iPhone will try to reconnect to that one even though it isn't bonded with it and has never seen it before, and will fail with an authentication error.

A significant amount of Googling eventually led me to this post: espressif/esp-nimble#24 It suggests that the problem is that all ESP32 NimBLE devices have the same Identity Resolving Key.

As I understand it, this means that the iPhone is effectively overwriting the encryption keys it stored from Device 1 with those of the newly-bonded Device 2, because it thinks they're the same device because the IRKs are the same. When Device 3 is booted, the iPhone thinks it's Device 1 as well.

The above link also notes that while there is a private API function to change the IRK, doing so erases all bonded devices, meaning that every time you restart the ESP32 you'll have to pair everything again.

The link also points to this patch, which provides a way to use a custom function to set the default IRK without erasing the bonding information. Blockstream/Jade@2227d29 IMO, the IRK should be randomly generated on startup if there are no bonded devices, but I may not understand the specifics of how BLE works here.

As it stands, I do not believe it is possible to have a single device like an iPhone connect to two or more ESP32 NimBLE devices at the same time due to the IRK conflicts, which is a rather significant limitation.

I've also come across posts like this, but it's for the core ESP32 NimBLE implementation, not the Arduino one, and it's not clear how I could apply it here:
https://esp32.com/viewtopic.php?t=14966

Does Arduino NimBLE need this patch, or some other method to improve IRK handling to resolve this? Or is there simply something that I'm doing wrong?

Thanks!

@h2zero
Copy link
Owner

h2zero commented May 14, 2023

Yes, the issue in espressif/esp-nimble#24 applies here as well sadly. Until this is fixed upstream it will be a problem sadly. There is a patch available in that issue thread that my work if you want to try it.

@jangellx
Copy link
Author

Thanks -- I'm just glad to know that I'm not doing something wrong. I'll give the patch a try.

I have another weird issue where I stop being able to connect to the ESP32 after some time, which varies from minutes to hours, and seems related to the phone moving in and out of Bluetooth range, or being right at the edge of it. I "solved" this by rebooting the ESP32 a short while after the last disconnect, but that's awful hacky. I'd open an issue on it, but while it's reasonably common, it's extremely difficult to reproduce intentionally, so there's not much useful information to put in an issue.

Anyway, I'll keep an eye out for Espresif or Apache or whoever to actually fix the IRK. Thanks again!

@h2zero
Copy link
Owner

h2zero commented Jun 4, 2024

I know this is old but have you been able to resolve this at all?

@jangellx
Copy link
Author

Sorry, I haven't been able to work on this project in a while, and when I have I've just been limping along with one IRK for now. I keep meaning back to, but get distracted by other projects.

Thanks to your prompt, I checked and saw that espressif/esp-nimble#24 is marked as closed as of February, so it sounds like nimble-1.5.0-idf has the fix. I have no idea what would be involved in updating NimBLE-Arduino to use that, though.

@h2zero
Copy link
Owner

h2zero commented Jun 10, 2024

@jangellx Take a look at #679

@jangellx
Copy link
Author

Ah, well that seems like it would do the trick! Thanks!

@ggibson-github
Copy link

How do we get the 1.5 Core update to show up in the Arduino Library Manager?

@h2zero
Copy link
Owner

h2zero commented Nov 3, 2024

It is not released yet, sorry. I haven't had time to get it ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants