Merge branch 'feature/adds_bootloader_rollback_configs' into 'master'

feat(bootloader): Adds bootloader anti rollback configs

See merge request espressif/esp-idf!34759
This commit is contained in:
Konstantin Kondrashov
2024-11-09 01:41:50 +08:00
6 changed files with 103 additions and 66 deletions

View File

@@ -0,0 +1,68 @@
menu "Application Rollback"
config BOOTLOADER_APP_ROLLBACK_ENABLE
bool "Enable app rollback support"
default n
help
After updating the app, the bootloader runs a new app with the "ESP_OTA_IMG_PENDING_VERIFY" state set.
This state prevents the re-run of this app. After the first boot of the new app in the user code, the
function should be called to confirm the operability of the app or vice versa about its non-operability.
If the app is working, then it is marked as valid. Otherwise, it is marked as not valid and rolls back to
the previous working app. A reboot is performed, and the app is booted before the software update.
Note: If during the first boot a new app the power goes out or the WDT works, then roll back will happen.
Rollback is possible only between the apps with the same security versions.
config BOOTLOADER_APP_ANTI_ROLLBACK
bool "Enable app anti-rollback support"
depends on BOOTLOADER_APP_ROLLBACK_ENABLE
default n
help
This option prevents rollback to previous firmware/application image with lower security version.
config BOOTLOADER_APP_SECURE_VERSION
int "eFuse secure version of app"
depends on BOOTLOADER_APP_ANTI_ROLLBACK
default 0
help
The secure version is the sequence number stored in the header of each firmware.
The security version is set in the bootloader, version is recorded in the eFuse field
as the number of set ones. The allocated number of bits in the efuse field
for storing the security version is limited (see BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD option).
Bootloader: When bootloader selects an app to boot, an app is selected that has
a security version greater or equal that recorded in eFuse field.
The app is booted with a higher (or equal) secure version.
The security version is worth increasing if in previous versions there is
a significant vulnerability and their use is not acceptable.
Your partition table should has a scheme with ota_0 + ota_1 (without factory).
config BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD
int "Size of the efuse secure version field"
depends on BOOTLOADER_APP_ANTI_ROLLBACK
range 1 32 if IDF_TARGET_ESP32
default 32 if IDF_TARGET_ESP32
range 1 4 if IDF_TARGET_ESP32C2
default 4 if IDF_TARGET_ESP32C2
range 1 16
default 16
help
The size of the efuse secure version field.
Its length is limited to 32 bits for ESP32 and 16 bits for ESP32-S2.
This determines how many times the security version can be increased.
config BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
bool "Emulate operations with efuse secure version(only test)"
default n
depends on BOOTLOADER_APP_ANTI_ROLLBACK
select EFUSE_VIRTUAL
select EFUSE_VIRTUAL_KEEP_IN_FLASH
help
This option allows to emulate read/write operations with all eFuses and efuse secure version.
It allows to test anti-rollback implementation without permanent write eFuse bits.
There should be an entry in partition table with following details: `emul_efuse, data, efuse, , 0x2000`.
This option enables: EFUSE_VIRTUAL and EFUSE_VIRTUAL_KEEP_IN_FLASH.
endmenu

View File

@@ -0,0 +1,25 @@
menu "Bootloader Rollback"
config BOOTLOADER_ANTI_ROLLBACK_ENABLE
bool "Enable bootloader rollback support"
depends on SOC_RECOVERY_BOOTLOADER_SUPPORTED
default n
help
This option prevents rollback to previous bootloader image with lower security version.
config BOOTLOADER_SECURE_VERSION
int "Secure version of bootloader"
depends on BOOTLOADER_ANTI_ROLLBACK_ENABLE
default 0
range 0 4
help
The secure version is the sequence number stored in the header of each bootloader.
The ROM Bootloader which runs the 2nd stage bootloader (PRIMARY or RECOVERY) checks that
the security version is greater or equal that recorded in the eFuse field.
Bootloaders that have a secure version in the image < secure version in efuse will not boot.
The security version is worth increasing if in previous versions there is
a significant vulnerability and their use is not acceptable.
endmenu

View File

@@ -1,6 +1,8 @@
menu "Bootloader config"
orsource "../esp_bootloader_format/Kconfig.bootloader"
orsource "Kconfig.app_rollback"
orsource "Kconfig.bootloader_rollback"
config BOOTLOADER_OFFSET_IN_FLASH
hex
@@ -312,71 +314,6 @@ menu "Bootloader config"
- these options can increase the execution time.
Note: RTC_WDT will reset while encryption operations will be performed.
config BOOTLOADER_APP_ROLLBACK_ENABLE
bool "Enable app rollback support"
default n
help
After updating the app, the bootloader runs a new app with the "ESP_OTA_IMG_PENDING_VERIFY" state set.
This state prevents the re-run of this app. After the first boot of the new app in the user code, the
function should be called to confirm the operability of the app or vice versa about its non-operability.
If the app is working, then it is marked as valid. Otherwise, it is marked as not valid and rolls back to
the previous working app. A reboot is performed, and the app is booted before the software update.
Note: If during the first boot a new app the power goes out or the WDT works, then roll back will happen.
Rollback is possible only between the apps with the same security versions.
config BOOTLOADER_APP_ANTI_ROLLBACK
bool "Enable app anti-rollback support"
depends on BOOTLOADER_APP_ROLLBACK_ENABLE
default n
help
This option prevents rollback to previous firmware/application image with lower security version.
config BOOTLOADER_APP_SECURE_VERSION
int "eFuse secure version of app"
depends on BOOTLOADER_APP_ANTI_ROLLBACK
default 0
help
The secure version is the sequence number stored in the header of each firmware.
The security version is set in the bootloader, version is recorded in the eFuse field
as the number of set ones. The allocated number of bits in the efuse field
for storing the security version is limited (see BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD option).
Bootloader: When bootloader selects an app to boot, an app is selected that has
a security version greater or equal that recorded in eFuse field.
The app is booted with a higher (or equal) secure version.
The security version is worth increasing if in previous versions there is
a significant vulnerability and their use is not acceptable.
Your partition table should has a scheme with ota_0 + ota_1 (without factory).
config BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD
int "Size of the efuse secure version field"
depends on BOOTLOADER_APP_ANTI_ROLLBACK
range 1 32 if IDF_TARGET_ESP32
default 32 if IDF_TARGET_ESP32
range 1 4 if IDF_TARGET_ESP32C2
default 4 if IDF_TARGET_ESP32C2
range 1 16
default 16
help
The size of the efuse secure version field.
Its length is limited to 32 bits for ESP32 and 16 bits for ESP32-S2.
This determines how many times the security version can be increased.
config BOOTLOADER_EFUSE_SECURE_VERSION_EMULATE
bool "Emulate operations with efuse secure version(only test)"
default n
depends on BOOTLOADER_APP_ANTI_ROLLBACK
select EFUSE_VIRTUAL
select EFUSE_VIRTUAL_KEEP_IN_FLASH
help
This option allows to emulate read/write operations with all eFuses and efuse secure version.
It allows to test anti-rollback implementation without permanent write eFuse bits.
There should be an entry in partition table with following details: `emul_efuse, data, efuse, , 0x2000`.
This option enables: EFUSE_VIRTUAL and EFUSE_VIRTUAL_KEEP_IN_FLASH.
config BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
bool "Skip image validation when exiting deep sleep"
# note: dependencies for this config item are different to other "skip image validation"

View File

@@ -17,6 +17,11 @@ __attribute__((weak))
const esp_bootloader_desc_t esp_bootloader_desc = {
.magic_byte = ESP_BOOTLOADER_DESC_MAGIC_BYTE,
.reserved = { 0 },
#if CONFIG_BOOTLOADER_ANTI_ROLLBACK_ENABLE
.secure_version = CONFIG_BOOTLOADER_SECURE_VERSION,
#else
.secure_version = 0,
#endif // CONFIG_BOOTLOADER_ANTI_ROLLBACK_ENABLE
.version = CONFIG_BOOTLOADER_PROJECT_VER,
.idf_ver = IDF_VER,
#ifdef CONFIG_BOOTLOADER_COMPILE_TIME_DATE

View File

@@ -24,7 +24,8 @@ extern "C"
*/
typedef struct {
uint8_t magic_byte; /*!< Magic byte ESP_BOOTLOADER_DESC_MAGIC_BYTE */
uint8_t reserved[3]; /*!< reserved for IDF */
uint8_t reserved[2]; /*!< reserved for IDF */
uint8_t secure_version; /*!< The version used by bootloader anti-rollback feature */
uint32_t version; /*!< Bootloader version */
char idf_ver[32]; /*!< Version IDF */
char date_time[24]; /*!< Compile date and time*/

View File

@@ -64,6 +64,7 @@ The ``DRAM0`` segment of the bootloader binary starts with the :cpp:type:`esp_bo
* ``magic_byte``: the magic byte for the esp_bootloader_desc structure
* ``reserved``: reserved for the future IDF use
* ``secure_version``: the secure version used by the bootloader anti-rollback feature, see :ref:`CONFIG_BOOTLOADER_ANTI_ROLLBACK_ENABLE`.
* ``version``: bootloader version, see :ref:`CONFIG_BOOTLOADER_PROJECT_VER`
* ``idf_ver``: ESP-IDF version. [#f1]_
* ``date`` and ``time``: compile date and time