Skip to content

Commit a2dc60b

Browse files
committed
Merge branch 'feature/secure_boot_esp32s2' into 'master'
Feature/secure boot esp32s2 See merge request espressif/esp-idf!8254
2 parents 16c73ed + b9a1d82 commit a2dc60b

File tree

28 files changed

+633
-108
lines changed

28 files changed

+633
-108
lines changed

components/app_update/esp_ota_ops.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@
4040
#include "esp_system.h"
4141
#include "esp_efuse.h"
4242

43+
#ifdef CONFIG_IDF_TARGET_ESP32
44+
#include "esp32/rom/crc.h"
45+
#elif CONFIG_IDF_TARGET_ESP32S2
46+
#include "esp32s2/rom/crc.h"
47+
#include "esp32s2/rom/secure_boot.h"
48+
#endif
4349

4450
#define SUB_TYPE_ID(i) (i & 0x0F)
4551

@@ -857,3 +863,24 @@ esp_err_t esp_ota_erase_last_boot_app_partition(void)
857863

858864
return ESP_OK;
859865
}
866+
867+
#if CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SECURE_BOOT_V2_ENABLED
868+
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index) {
869+
870+
if (!esp_secure_boot_enabled()) {
871+
ESP_LOGE(TAG, "Secure boot v2 has not been enabled.");
872+
return ESP_FAIL;
873+
}
874+
875+
if (index != SECURE_BOOT_PUBLIC_KEY_INDEX_0 &&
876+
index != SECURE_BOOT_PUBLIC_KEY_INDEX_1 &&
877+
index != SECURE_BOOT_PUBLIC_KEY_INDEX_2) {
878+
ESP_LOGE(TAG, "Invalid Index found for public key revocation %d.", index);
879+
return ESP_ERR_INVALID_ARG;
880+
}
881+
882+
ets_secure_boot_revoke_public_key_digest(index);
883+
ESP_LOGI(TAG, "Revoked signature block %d.", index);
884+
return ESP_OK;
885+
}
886+
#endif

components/app_update/include/esp_ota_ops.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,34 @@ esp_err_t esp_ota_erase_last_boot_app_partition(void);
299299
*/
300300
bool esp_ota_check_rollback_is_possible(void);
301301

302+
#if CONFIG_IDF_TARGET_ESP32S2 && (CONFIG_SECURE_BOOT_V2_ENABLED || __DOXYGEN__)
303+
304+
/**
305+
* Secure Boot V2 public key indexes.
306+
*/
307+
typedef enum {
308+
SECURE_BOOT_PUBLIC_KEY_INDEX_0, /*!< Points to the 0th index of the Secure Boot v2 public key */
309+
SECURE_BOOT_PUBLIC_KEY_INDEX_1, /*!< Points to the 1st index of the Secure Boot v2 public key */
310+
SECURE_BOOT_PUBLIC_KEY_INDEX_2 /*!< Points to the 2nd index of the Secure Boot v2 public key */
311+
} esp_ota_secure_boot_public_key_index_t;
312+
313+
/**
314+
* @brief Revokes the old signature digest. To be called in the application after the rollback logic.
315+
*
316+
* Relevant for Secure boot v2 on ESP32-S2 where upto 3 key digests can be stored (Key #N-1, Key #N, Key #N+1).
317+
* When key #N-1 used to sign an app is invalidated, an OTA update is to be sent with an app signed with key #N-1 & Key #N.
318+
* After successfully booting the OTA app should call this function to revoke Key #N-1.
319+
*
320+
* @param index - The index of the signature block to be revoked
321+
*
322+
* @return
323+
* - ESP_OK: If revocation is successful.
324+
* - ESP_ERR_INVALID_ARG: If the index of the public key to be revoked is incorrect.
325+
* - ESP_FAIL: If secure boot v2 has not been enabled.
326+
*/
327+
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index);
328+
#endif /* CONFIG_IDF_TARGET_ESP32S2 */
329+
302330
#ifdef __cplusplus
303331
}
304332
#endif

components/bootloader/Kconfig.projbuild

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ menu "Security features"
383383

384384
config SECURE_SIGNED_APPS_RSA_SCHEME
385385
bool "RSA"
386-
depends on ESP32_REV_MIN_3 && SECURE_BOOT_V2_ENABLED
386+
depends on (ESP32_REV_MIN_3 || IDF_TARGET_ESP32S2) && SECURE_BOOT_V2_ENABLED
387387
help
388388
Appends the RSA-3072 based Signature block to the application.
389389
Refer to <Secure Boot Version 2 documentation link> before enabling.
@@ -447,7 +447,9 @@ menu "Security features"
447447

448448
config SECURE_BOOT_V2_ENABLED
449449
bool "Enable Secure Boot version 2"
450-
depends on ESP32_REV_MIN_3
450+
depends on ESP32_REV_MIN_3 || IDF_TARGET_ESP32S2
451+
select SECURE_ENABLE_SECURE_ROM_DL_MODE if IDF_TARGET_ESP32S2 && !SECURE_INSECURE_ALLOW_DL_MODE
452+
select SECURE_DISABLE_ROM_DL_MODE if ESP32_REV_MIN_3 && !SECURE_INSECURE_ALLOW_DL_MODE
451453
help
452454
Build a bootloader which enables Secure Boot version 2 on first boot.
453455
Refer to Secure Boot V2 section of the ESP-IDF Programmer's Guide for this version before enabling.
@@ -681,6 +683,19 @@ menu "Security features"
681683
key digest, causing an immediate denial of service and possibly allowing an additional fault
682684
injection attack to bypass the signature protection.
683685

686+
config SECURE_INSECURE_ALLOW_DL_MODE
687+
bool "Don't automatically restrict UART download mode"
688+
depends on SECURE_BOOT_INSECURE && SECURE_BOOT_V2_ENABLED
689+
default N
690+
help
691+
By default, enabling either flash encryption in release mode or secure boot will automatically
692+
disable UART download mode on ESP32 ECO3, or enable secure download mode on newer chips.
693+
This is recommended to reduce the attack surface of the chip.
694+
695+
To allow the full UART download mode to stay enabled, enable this option and ensure
696+
the options SECURE_DISABLE_ROM_DL_MODE and SECURE_ENABLE_SECURE_ROM_DL_MODE are disabled as applicable.
697+
This is not recommended.
698+
684699
config SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
685700
bool "Leave UART bootloader encryption enabled"
686701
depends on SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT

components/bootloader/subproject/CMakeLists.txt

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,15 @@ endif()
9292

9393
if(CONFIG_SECURE_BOOT_V2_ENABLED)
9494
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
95-
get_filename_component(secure_boot_signing_key
95+
get_filename_component(secure_boot_signing_key
9696
"${SECURE_BOOT_SIGNING_KEY}" ABSOLUTE BASE_DIR "${project_dir}")
9797

9898
if(NOT EXISTS "${secure_boot_signing_key}")
99-
message(FATAL_ERROR
100-
"Secure Boot Signing Key Not found."
101-
"\nGenerate the Secure Boot V2 RSA-PSS 3072 Key."
102-
"\nTo generate one, you can use this command:"
103-
"\n\t${espsecurepy} generate_signing_key --version 2 ${SECURE_BOOT_SIGNING_KEY}")
99+
message(FATAL_ERROR
100+
"Secure Boot Signing Key Not found."
101+
"\nGenerate the Secure Boot V2 RSA-PSS 3072 Key."
102+
"\nTo generate one, you can use this command:"
103+
"\n\t${espsecurepy} generate_signing_key --version 2 ${SECURE_BOOT_SIGNING_KEY}")
104104
endif()
105105

106106
set(bootloader_unsigned_bin "bootloader-unsigned.bin")
@@ -117,7 +117,7 @@ if(CONFIG_SECURE_BOOT_V2_ENABLED)
117117
else()
118118
add_custom_command(OUTPUT ".signed_bin_timestamp"
119119
VERBATIM
120-
COMMENT "Bootloader generated but not signed")
120+
COMMENT "Bootloader generated but not signed")
121121
endif()
122122

123123
add_custom_target (gen_signed_bootloader ALL DEPENDS "${build_dir}/.signed_bin_timestamp")
@@ -166,6 +166,24 @@ elseif(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
166166
"* Not recommended to re-use the same secure boot keyfile on multiple production devices."
167167
DEPENDS gen_secure_bootloader_key gen_bootloader_digest_bin
168168
VERBATIM)
169+
elseif(CONFIG_SECURE_BOOT_V2_ENABLED AND CONFIG_IDF_TARGET_ESP32S2)
170+
add_custom_command(TARGET bootloader.elf POST_BUILD
171+
COMMAND ${CMAKE_COMMAND} -E echo
172+
"=============================================================================="
173+
COMMAND ${CMAKE_COMMAND} -E echo
174+
"Bootloader built. Secure boot enabled, so bootloader not flashed automatically."
175+
COMMAND ${CMAKE_COMMAND} -E echo
176+
"To sign the bootloader with additional private keys."
177+
COMMAND ${CMAKE_COMMAND} -E echo
178+
"\t${espsecurepy} sign_data -k secure_boot_signing_key2.pem -v 2 --append_signatures -o signed_bootloader.bin build/bootloader/bootloader.bin"
179+
COMMAND ${CMAKE_COMMAND} -E echo
180+
"Secure boot enabled, so bootloader not flashed automatically."
181+
COMMAND ${CMAKE_COMMAND} -E echo
182+
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
183+
COMMAND ${CMAKE_COMMAND} -E echo
184+
"=============================================================================="
185+
DEPENDS gen_signed_bootloader
186+
VERBATIM)
169187
elseif(CONFIG_SECURE_BOOT_V2_ENABLED)
170188
add_custom_command(TARGET bootloader.elf POST_BUILD
171189
COMMAND ${CMAKE_COMMAND} -E echo

components/bootloader/subproject/main/ld/esp32s2/bootloader.ld

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
MEMORY
77
{
8-
iram_seg (RWX) : org = 0x40050000, len = 0x4000 /* 16KB, SRAM Block_14 */
9-
iram_loader_seg (RWX) : org = 0x40054000, len = 0x4000 /* 16KB, SRAM Block_15 */
10-
dram_seg (RW) : org = 0x3FFE8000, len = 0x2800 /* 10KB, Top of SRAM Block_16, and before ROM data and stack */
8+
iram_seg (RWX) : org = 0x4004c000, len = 0x4000 /* SRAM Block 13 */
9+
iram_loader_seg (RWX) : org = 0x40050000, len = 0x6000 /* SRAM Block 14 & part of 15 */
10+
dram_seg (RW) : org = 0x3FFE6000, len = 0x4B00 /* Part SRAM Blocks 15 & 16, ROM static buffer starts at end of this region (reclaimed after app runs) */
1111
}
1212

1313
/* Default entry point: */

components/bootloader_support/src/bootloader_utility.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ void bootloader_debug_buffer(const void *buffer, size_t length, const char *labe
819819

820820
esp_err_t bootloader_sha256_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest)
821821
{
822+
822823
if (digest == NULL) {
823824
return ESP_ERR_INVALID_ARG;
824825
}
@@ -835,7 +836,7 @@ esp_err_t bootloader_sha256_flash_contents(uint32_t flash_offset, uint32_t len,
835836
while (len > 0) {
836837
uint32_t mmu_page_offset = ((flash_offset & MMAP_ALIGNED_MASK) != 0) ? 1 : 0; /* Skip 1st MMU Page if it is already populated */
837838
uint32_t partial_image_len = MIN(len, ((mmu_free_pages_count - mmu_page_offset) * SPI_FLASH_MMU_PAGE_SIZE)); /* Read the image that fits in the free MMU pages */
838-
839+
839840
const void * image = bootloader_mmap(flash_offset, partial_image_len);
840841
if (image == NULL) {
841842
bootloader_sha256_finish(sha_handle, NULL);

components/bootloader_support/src/esp32/secure_boot.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,17 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
391391
ESP_LOGW(TAG, "Not disabling ROM BASIC fallback - SECURITY COMPROMISED");
392392
#endif
393393

394+
#ifdef CONFIG_SECURE_DISABLE_ROM_DL_MODE
395+
ESP_LOGI(TAG, "Disable ROM Download mode...");
396+
esp_err_t err = esp_efuse_disable_rom_download_mode();
397+
if (err != ESP_OK) {
398+
ESP_LOGE(TAG, "Could not disable ROM Download mode...");
399+
return ESP_FAIL;
400+
}
401+
#else
402+
ESP_LOGW(TAG, "Not disabling ROM Download mode - SECURITY COMPROMISED");
403+
#endif
404+
394405
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
395406
bool rd_dis_now = true;
396407
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED

0 commit comments

Comments
 (0)