ESP32 OTA Anti-Rollback with Factory Partition.

NotMyRealName
Posts: 41
Joined: Thu Feb 13, 2020 1:35 am

ESP32 OTA Anti-Rollback with Factory Partition.

Postby NotMyRealName » Mon Jan 25, 2021 4:53 am

Hi All,

Looking for a bit more information, so hoping someone can help. I see in the OTA Anti-Rollback docs (https://docs.espressif.com/projects/esp ... -scheme-is) that the anti-rollback has a restriction that there should not be a factory app partition.

Is there any reason for this other than the fact that there is no (standard) method for updating the factory partition (and therefore its secure version)? I have a manual method for updating the factory partition that I can trigger before or during a secure version change process. I still want to keep the factory app as a way of 'resetting to factory defaults'.

I assume the inherent behavior is:

VALID FACTORY APP SECURE VERSION:
Boot Factory partition or newest OTA with valid secure version.

OLD FACTORY APP SECURE VERSION:
Boot newest OTA image that has valid secure version. (Or get stuck in an error loop if nothing is valid).

I'm hoping I can keep the Factory partition if I am careful. :)

NotMyRealName
Posts: 41
Joined: Thu Feb 13, 2020 1:35 am

Re: ESP32 OTA Anti-Rollback with Factory Partition.

Postby NotMyRealName » Mon Jan 25, 2021 6:28 am

I see that the tools (esp-2020r3-8.4.0) are actually actively looking for this and generating an exception. But you can still use a test partition with secure version enabled? I can't see a lot of difference? Presumably the bootloader still checks the secure version of a test application?

NotMyRealName
Posts: 41
Joined: Thu Feb 13, 2020 1:35 am

Re: ESP32 OTA Anti-Rollback with Factory Partition.

Postby NotMyRealName » Mon Jan 25, 2021 8:55 pm

Update:

I've tested the anti-rollback with the test app using the option to simulate efuses and this seems to be a bad idea. With this code (IDF v4.2) the boot-loader does not seem to check the secure version of the test app. This means that if the OTA partitions are invalid (i.e. secure version is too low) the boot-loader won't run them but will blindly run the test app with a lower secure version. It does however check the signature of the test app.

NOTE: I have it configured to launch the test app from a GPIO pin boot, but as the default behavior is to run the test app if no other partitions are found this is a bit of a security hole. You could very easily force running insecure code by corrupting or loading invalid code onto all OTA partitions. So obviously running a test app is not a good idea with anti-rollback either.

I'm trying to provide a recovery method for our product in the event that updates mess things up. I liked the factory partition option to trigger a safe version of code off a GPIO at boot. I'd ideally want a way to be able to maintain a special image on the device that is trusted and updated less often for this purpose. I'm still OK with updating it sometimes in order to facilitate secure version changes etc. Does anyone know of a way to do this?

ESP_Mahavir
Posts: 190
Joined: Wed Jan 24, 2018 6:51 am

Re: ESP32 OTA Anti-Rollback with Factory Partition.

Postby ESP_Mahavir » Tue Jan 26, 2021 5:47 am

Hello,

Your understanding is correct. Bootloader tries to boot from `factory` partition as fallback method if bootup from other partition fails due to various reasons. In addition, `factory` partition is non-upgradable entity, because unlike firmware it does not have identical partition to handle power failure scenarios. This would have allowed anyone with physical access to device to erase `otadata` partition and force boot up from `factory` partition. Considering all this (and to keep software design simple), we recommend to combine `factory` partition logic in primary firmware which can be entered through some user initiated action (like long button press) in case of anti-rollback feature.

You may find writeup at https://medium.com/the-esp-journal/ota- ... 5438e30c12 useful in this context.

NOTE: I have it configured to launch the test app from a GPIO pin boot, but as the default behavior is to run the test app if no other partitions are found this is a bit of a security hole. You could very easily force running insecure code by corrupting or loading invalid code onto all OTA partitions. So obviously running a test app is not a good idea with anti-rollback either.

I am little unclear on experiment here, can you please explain? Are you trying anti-rollback scheme with factory partition and facing these issues? Interim, writeup I mentioned above has example code that was tested using:

Code: Select all

CONFIG_BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE=y
Thanks.

NotMyRealName
Posts: 41
Joined: Thu Feb 13, 2020 1:35 am

Re: ESP32 OTA Anti-Rollback with Factory Partition.

Postby NotMyRealName » Tue Jan 26, 2021 7:15 pm

Hi Mahavir,

The experiment I described was using a different boot feature. Separate to factory app reset behavior, there is also an option to run a user test app when holding a GPIO low at boot. I tried this as an alternative means of doing what I want and found the boot-loader didn't check the secure version of the test app partition.

I think you can actually update the factory partition fairly safely if you have OTA partitions because the OTA images themselves provide the second copy of firmware to make it failure tolerant. Some time ago I wrote a routine in my firmware where I could trigger the firmware to copy itself from an OTA partition to the factory partition as a means of updating it. I found when I tested it that if i pulled the power half way through (to corrupt the factory partition) it would still boot the OTA partition just fine and it recovered ok. I presume this is because the 'otadata ' partition was still intact, though I wouldn't be surprised if the bootloader still checked the OTA images if it did get erased.

Konstantin
Posts: 13
Joined: Tue Feb 05, 2019 7:31 am

Re: ESP32 OTA Anti-Rollback with Factory Partition.

Postby Konstantin » Mon Feb 01, 2021 2:39 pm

Hi NotMyRealName!
NOTE: I have it configured to launch the test app from a GPIO pin boot, but as the default behavior is to run the test app if no other partitions are found this is a bit of a security hole. You could very easily force running insecure code by corrupting or loading invalid code onto all OTA partitions. So obviously running a test app is not a good idea with anti-rollback either.
The test app can be run (if exists in the partition_table and in the test_app slot) in case:
1. Press a GPIO pin (CONFIG_BOOTLOADER_NUM_PIN_APP_TEST).
2. If there is not any other bootable app.
Running test_app there is no secure version check but is the check of signature (if CONFIG_SECURE_SIGNED_ON_BOOT is on).

You should not use the test_app in a couple with anti-rollback. I will block the option CONFIG_BOOTLOADER_APP_TEST in this case.
In the Kconfig, the BOOTLOADER_APP_TEST will depend on !BOOTLOADER_APP_ANTI_ROLLBACK. And addition to the build system will fail if test_app exists in the partition_table.
It should resolve this security hole.

NotMyRealName
Posts: 41
Joined: Thu Feb 13, 2020 1:35 am

Re: ESP32 OTA Anti-Rollback with Factory Partition.

Postby NotMyRealName » Mon Feb 01, 2021 8:18 pm

Hi Konstantin,

Thanks, that would be a good minimum step. I guess what I am trying to understand though that no one has yet been able to shed some light on is why can't the boot-loader just check the secure version as well so that this option can be safely left enabled?

I don't see a reason why this wouldn't work if you are willing to have the test app fail to boot when the button is held down if it is out of date, and can manually update it so that this doesn't normally happen. Or alternatively to do the same thing with the factory app partition and have it fail to roll back to the factory partition if its secure version is too low? The rollback mechanism doesn't always work in all circumstances at the moment anyway. If the rollback fails, you are essentially in the same situation where you must rely solely on the OTA partitions.

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 413 guests