espressif: update secure boot and flash encryption
Adjust secure boot and flash encryption after IDF v5.x updates.
It also allows to enable secure boot on ESP32-C2.
Signed-off-by: Almir Okato <almir.okato@espressif.com>
diff --git a/boot/espressif/hal/CMakeLists.txt b/boot/espressif/hal/CMakeLists.txt
index 7f3d1bb..d248c26 100644
--- a/boot/espressif/hal/CMakeLists.txt
+++ b/boot/espressif/hal/CMakeLists.txt
@@ -71,11 +71,8 @@
${esp_hal_dir}/components/bootloader_support/src/bootloader_random_${MCUBOOT_TARGET}.c
${esp_hal_dir}/components/bootloader_support/src/bootloader_utility.c
${esp_hal_dir}/components/bootloader_support/src/esp_image_format.c
- ${esp_hal_dir}/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c
${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/bootloader_soc.c
${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/bootloader_sha.c
- ${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/secure_boot_secure_features.c
- ${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/flash_encryption_secure_features.c
${esp_hal_dir}/components/hal/mpu_hal.c
${esp_hal_dir}/components/hal/efuse_hal.c
${esp_hal_dir}/components/hal/mmu_hal.c
@@ -103,12 +100,23 @@
if(DEFINED CONFIG_SECURE_BOOT_V2_ENABLED)
list(APPEND hal_srcs
${src_dir}/secure_boot.c
+ ${esp_hal_dir}/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_bootloader.c
+ ${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/secure_boot_secure_features.c
+ )
+ list(APPEND include_dirs
+ ${esp_hal_dir}/components/bootloader_support/src/secure_boot_v2
)
endif()
if(DEFINED CONFIG_SECURE_FLASH_ENC_ENABLED)
list(APPEND hal_srcs
${src_dir}/flash_encrypt.c
+ ${esp_hal_dir}/components/bootloader_support/src/${MCUBOOT_TARGET}/flash_encryption_secure_features.c
+ )
+ set_source_files_properties(
+ ${src_dir}/flash_encrypt.c
+ PROPERTIES COMPILE_FLAGS
+ "-Wno-unused-variable"
)
endif()
diff --git a/boot/espressif/hal/include/esp32c6/esp32c6.cmake b/boot/espressif/hal/include/esp32c6/esp32c6.cmake
index 23b6b00..d26c5f0 100644
--- a/boot/espressif/hal/include/esp32c6/esp32c6.cmake
+++ b/boot/espressif/hal/include/esp32c6/esp32c6.cmake
@@ -8,7 +8,7 @@
list(APPEND hal_srcs
${esp_hal_dir}/components/hal/cache_hal.c
- ${esp_hal_dir}/components/hal/${MCUBOOT_TARGET}/lp_timer_hal.c
+ ${esp_hal_dir}/components/hal/lp_timer_hal.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_regi2c_${MCUBOOT_TARGET}.c
)
diff --git a/boot/espressif/hal/include/esp32h2/esp32h2.cmake b/boot/espressif/hal/include/esp32h2/esp32h2.cmake
index 9160eab..d26c5f0 100644
--- a/boot/espressif/hal/include/esp32h2/esp32h2.cmake
+++ b/boot/espressif/hal/include/esp32h2/esp32h2.cmake
@@ -8,6 +8,7 @@
list(APPEND hal_srcs
${esp_hal_dir}/components/hal/cache_hal.c
+ ${esp_hal_dir}/components/hal/lp_timer_hal.c
${esp_hal_dir}/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
${esp_hal_dir}/components/esp_rom/patches/esp_rom_regi2c_${MCUBOOT_TARGET}.c
)
diff --git a/boot/espressif/hal/src/flash_encrypt.c b/boot/espressif/hal/src/flash_encrypt.c
index 222e32e..d064d8b 100644
--- a/boot/espressif/hal/src/flash_encrypt.c
+++ b/boot/espressif/hal/src/flash_encrypt.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -15,7 +15,11 @@
#include "esp_efuse_table.h"
#include "esp_log.h"
#include "hal/wdt_hal.h"
+#include "hal/efuse_hal.h"
#include "soc/soc_caps.h"
+#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
+#include "soc/sensitive_reg.h"
+#endif
#include "esp_mcuboot_image.h"
@@ -27,6 +31,8 @@
#define WR_DIS_CRYPT_CNT ESP_EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT
#endif
+#define FLASH_ENC_CNT_MAX (CRYPT_CNT[0]->bit_count)
+
/* This file implements FLASH ENCRYPTION related APIs to perform
* various operations such as programming necessary flash encryption
* eFuses, detect whether flash encryption is enabled (by reading eFuse)
@@ -36,10 +42,9 @@
static const char *TAG = "flash_encrypt";
/* Static functions for stages of flash encryption */
-static esp_err_t initialise_flash_encryption(void);
-static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis) __attribute__((unused));
static esp_err_t encrypt_bootloader(void);
static esp_err_t encrypt_primary_slot(void);
+static size_t get_flash_encrypt_cnt_value(void);
/**
* This former inlined function must not be defined in the header file anymore.
@@ -50,16 +55,15 @@
*/
bool IRAM_ATTR esp_flash_encryption_enabled(void)
{
- uint32_t flash_crypt_cnt = 0;
#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
- flash_crypt_cnt = efuse_ll_get_flash_crypt_cnt();
+ return efuse_hal_flash_encryption_enabled();
#else
+ uint32_t flash_crypt_cnt = 0;
#if CONFIG_IDF_TARGET_ESP32
esp_efuse_read_field_blob(ESP_EFUSE_FLASH_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_FLASH_CRYPT_CNT[0]->bit_count);
#else
esp_efuse_read_field_blob(ESP_EFUSE_SPI_BOOT_CRYPT_CNT, &flash_crypt_cnt, ESP_EFUSE_SPI_BOOT_CRYPT_CNT[0]->bit_count);
#endif
-#endif
/* __builtin_parity is in flash, so we calculate parity inline */
bool enabled = false;
while (flash_crypt_cnt) {
@@ -69,34 +73,84 @@
flash_crypt_cnt >>= 1;
}
return enabled;
+#endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
}
-esp_err_t esp_flash_encrypt_check_and_update(void)
+static size_t get_flash_encrypt_cnt_value(void)
{
size_t flash_crypt_cnt = 0;
esp_efuse_read_field_cnt(CRYPT_CNT, &flash_crypt_cnt);
- bool flash_crypt_wr_dis = esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT);
+ return flash_crypt_cnt;
+}
+
+bool esp_flash_encrypt_initialized_once(void)
+{
+ return get_flash_encrypt_cnt_value() != 0;
+}
+
+bool esp_flash_encrypt_is_write_protected(bool print_error)
+{
+ if (esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT)) {
+ if (print_error) {
+ ESP_LOGE(TAG, "Flash Encryption cannot be enabled (CRYPT_CNT (%d) is write protected)", get_flash_encrypt_cnt_value());
+ }
+ return true;
+ }
+ return false;
+}
+
+bool esp_flash_encrypt_state(void)
+{
+ size_t flash_crypt_cnt = get_flash_encrypt_cnt_value();
+ bool flash_crypt_wr_dis = esp_flash_encrypt_is_write_protected(false);
ESP_LOGV(TAG, "CRYPT_CNT %d, write protection %d", flash_crypt_cnt, flash_crypt_wr_dis);
if (flash_crypt_cnt % 2 == 1) {
/* Flash is already encrypted */
- int left = (CRYPT_CNT[0]->bit_count - flash_crypt_cnt) / 2;
+ int left = (FLASH_ENC_CNT_MAX - flash_crypt_cnt) / 2;
if (flash_crypt_wr_dis) {
left = 0; /* can't update FLASH_CRYPT_CNT, no more flashes */
}
ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
- return ESP_OK;
- } else {
+ return true;
+ }
+ return false;
+}
+
+esp_err_t esp_flash_encrypt_check_and_update(void)
+{
+ bool flash_encryption_enabled = esp_flash_encrypt_state();
+ if (!flash_encryption_enabled) {
#ifndef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
- /* Flash is not encrypted, so encrypt it! */
- return encrypt_flash_contents(flash_crypt_cnt, flash_crypt_wr_dis);
+ if (esp_flash_encrypt_is_write_protected(true)) {
+ return ESP_FAIL;
+ }
+
+ esp_err_t err = esp_flash_encrypt_init();
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "Initialization of Flash encryption key failed (%d)", err);
+ return err;
+ }
+
+ err = esp_flash_encrypt_contents();
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "Encryption flash contents failed (%d)", err);
+ return err;
+ }
+
+ err = esp_flash_encrypt_enable();
+ if (err != ESP_OK) {
+ ESP_LOGE(TAG, "Enabling of Flash encryption failed (%d)", err);
+ return err;
+ }
#else
ESP_LOGE(TAG, "flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED "
"is set, refusing to boot.");
return ESP_ERR_INVALID_STATE;
#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
}
+ return ESP_OK;
}
static esp_err_t check_and_generate_encryption_keys(void)
@@ -127,10 +181,18 @@
return ESP_ERR_INVALID_STATE;
}
#else
+#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_AES128_DERIVED
+ enum { BLOCKS_NEEDED = 1 };
+ esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
+ ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS,
+ };
+ key_size = 16;
+#else
enum { BLOCKS_NEEDED = 1 };
esp_efuse_purpose_t purposes[BLOCKS_NEEDED] = {
ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY,
};
+#endif // CONFIG_SECURE_FLASH_ENCRYPTION_AES128_DERIVED
#endif // CONFIG_SECURE_FLASH_ENCRYPTION_AES256
#endif // CONFIG_IDF_TARGET_ESP32
@@ -181,8 +243,14 @@
return ESP_OK;
}
-static esp_err_t initialise_flash_encryption(void)
+esp_err_t esp_flash_encrypt_init(void)
{
+ if (esp_flash_encryption_enabled() || esp_flash_encrypt_initialized_once()) {
+ return ESP_OK;
+ }
+
+ /* Very first flash encryption pass: generate keys, etc. */
+
esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
/* Before first flash encryption pass, need to initialise key & crypto config */
@@ -198,26 +266,6 @@
return err;
}
-#if defined(SOC_SUPPORTS_SECURE_DL_MODE) && defined(CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE)
- ESP_LOGI(TAG, "Enabling Secure Download mode...");
- err = esp_efuse_enable_rom_secure_download_mode();
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "Could not enable Secure Download mode...");
- esp_efuse_batch_write_cancel();
- return err;
- }
-#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE
- ESP_LOGI(TAG, "Disable ROM Download mode...");
- err = esp_efuse_disable_rom_download_mode();
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "Could not disable ROM Download mode...");
- esp_efuse_batch_write_cancel();
- return err;
- }
-#else
- ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
-#endif
-
err = esp_efuse_batch_write_commit();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
@@ -228,24 +276,13 @@
}
/* Encrypt all flash data that should be encrypted */
-static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis)
+esp_err_t esp_flash_encrypt_contents(void)
{
esp_err_t err;
- /* If all flash_crypt_cnt bits are burned or write-disabled, the
- device can't re-encrypt itself. */
- if (flash_crypt_wr_dis || flash_crypt_cnt == CRYPT_CNT[0]->bit_count) {
- ESP_LOGE(TAG, "Cannot re-encrypt data CRYPT_CNT %d write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
- return ESP_FAIL;
- }
-
- if (flash_crypt_cnt == 0) {
- /* Very first flash of encrypted data: generate keys, etc. */
- err = initialise_flash_encryption();
- if (err != ESP_OK) {
- return err;
- }
- }
+#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
+ REG_WRITE(SENSITIVE_XTS_AES_KEY_UPDATE_REG, 1);
+#endif
err = encrypt_bootloader();
if (err != ESP_OK) {
@@ -292,22 +329,50 @@
}
#endif
-#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
- // Go straight to max, permanently enabled
- ESP_LOGI(TAG, "Setting CRYPT_CNT for permanent encryption");
- size_t new_flash_crypt_cnt = CRYPT_CNT[0]->bit_count - flash_crypt_cnt;
-#else
- /* Set least significant 0-bit in flash_crypt_cnt */
- size_t new_flash_crypt_cnt = 1;
-#endif
- ESP_LOGD(TAG, "CRYPT_CNT %d -> %d", flash_crypt_cnt, new_flash_crypt_cnt);
- err = esp_efuse_write_field_cnt(CRYPT_CNT, new_flash_crypt_cnt);
-
ESP_LOGI(TAG, "Flash encryption completed");
return ESP_OK;
}
+esp_err_t esp_flash_encrypt_enable(void)
+{
+ esp_err_t err = ESP_OK;
+ if (!esp_flash_encryption_enabled()) {
+
+ if (esp_flash_encrypt_is_write_protected(true)) {
+ return ESP_FAIL;
+ }
+
+ size_t flash_crypt_cnt = get_flash_encrypt_cnt_value();
+
+#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
+ // Go straight to max, permanently enabled
+ ESP_LOGI(TAG, "Setting CRYPT_CNT for permanent encryption");
+ size_t new_flash_crypt_cnt = FLASH_ENC_CNT_MAX - flash_crypt_cnt;
+#else
+ /* Set least significant 0-bit in flash_crypt_cnt */
+ size_t new_flash_crypt_cnt = 1;
+#endif
+ ESP_LOGD(TAG, "CRYPT_CNT %d -> %d", flash_crypt_cnt, new_flash_crypt_cnt);
+ err = esp_efuse_write_field_cnt(CRYPT_CNT, new_flash_crypt_cnt);
+
+#if defined(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE) && defined(CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128_DERIVED)
+ // For AES128_DERIVED, FE key is 16 bytes and XTS_KEY_LENGTH_256 is 0.
+ // It is important to protect XTS_KEY_LENGTH_256 from further changing it to 1. Set write protection for this bit.
+ // Burning WR_DIS_CRYPT_CNT, blocks further changing of eFuses: DOWNLOAD_DIS_MANUAL_ENCRYPT, SPI_BOOT_CRYPT_CNT, [XTS_KEY_LENGTH_256], SECURE_BOOT_EN.
+ esp_efuse_write_field_bit(WR_DIS_CRYPT_CNT);
+#endif
+ }
+
+ ESP_LOGI(TAG, "Flash encryption completed");
+
+#ifdef CONFIG_EFUSE_VIRTUAL
+ ESP_LOGW(TAG, "Flash encryption not really completed. Must disable virtual efuses");
+#endif
+
+ return err;
+}
+
static esp_err_t encrypt_bootloader(void)
{
esp_err_t err;
diff --git a/boot/espressif/hal/src/secure_boot.c b/boot/espressif/hal/src/secure_boot.c
index f724f0e..8ad29ae 100644
--- a/boot/espressif/hal/src/secure_boot.c
+++ b/boot/espressif/hal/src/secure_boot.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,7 +14,8 @@
#include "esp_image_format.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
-#include "rom/secure_boot.h"
+#include "secure_boot_signature_priv.h"
+
/* The following API implementations are used only when called
* from the bootloader code.
@@ -99,12 +100,20 @@
/* Generating the SHA of the public key components in the signature block */
bootloader_sha256_handle_t sig_block_sha;
sig_block_sha = bootloader_sha256_start();
+#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
bootloader_sha256_data(sig_block_sha, &block->key, sizeof(block->key));
+#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
+ bootloader_sha256_data(sig_block_sha, &block->ecdsa.key, sizeof(block->ecdsa.key));
+#endif
bootloader_sha256_finish(sig_block_sha, key_digest);
// Check we can verify the image using this signature and this key
uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
+#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
bool verified = ets_rsa_pss_verify(&block->key, block->signature, image_digest, temp_verified_digest);
+#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
+ bool verified = ets_ecdsa_verify(&block->ecdsa.key.point[0], block->ecdsa.signature, block->ecdsa.key.curve_id, image_digest, temp_verified_digest);
+#endif
if (!verified) {
/* We don't expect this: the signature blocks before we enable secure boot should all be verifiable or invalid,
@@ -133,21 +142,22 @@
{
esp_err_t ret;
#ifdef CONFIG_IDF_TARGET_ESP32
- esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
- ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
- };
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK_SECURE_BOOT);
if (coding_scheme != EFUSE_CODING_SCHEME_NONE) {
ESP_LOGE(TAG, "No coding schemes are supported in secure boot v2.(Detected scheme: 0x%x)", coding_scheme);
return ESP_ERR_NOT_SUPPORTED;
}
-#else
+#endif // CONFIG_IDF_TARGET_ESP32
+
esp_efuse_purpose_t secure_boot_key_purpose[SECURE_BOOT_NUM_BLOCKS] = {
+#if SECURE_BOOT_NUM_BLOCKS == 1
+ ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_V2,
+#else
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1,
ESP_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2,
+#endif
};
-#endif // CONFIG_IDF_TARGET_ESP32
/* Verify the bootloader */
esp_image_metadata_t bootloader_data = { 0 };
@@ -209,17 +219,24 @@
continue;
}
#endif
+#ifndef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
if (esp_efuse_get_key_dis_read(blocks[i])) {
ESP_LOGE(TAG, "Key digest (BLK%d) read protected, aborting...", blocks[i]);
return ESP_FAIL;
}
+#endif
if (esp_efuse_block_is_empty(blocks[i])) {
ESP_LOGE(TAG, "%d eFuse block is empty, aborting...", blocks[i]);
return ESP_FAIL;
}
esp_efuse_set_key_dis_write(blocks[i]);
- ret = esp_efuse_read_block(blocks[i], boot_key_digests.key_digests[boot_key_digests.num_digests], 0,
- sizeof(boot_key_digests.key_digests[0]) * 8);
+#ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
+ size_t offset = 128;
+#else
+ size_t offset = 0;
+#endif
+ ret = esp_efuse_read_block(blocks[i], boot_key_digests.key_digests[boot_key_digests.num_digests], offset,
+ ESP_SECURE_BOOT_KEY_DIGEST_LEN * 8);
if (ret) {
ESP_LOGE(TAG, "Error during reading %d eFuse block (err=0x%x)", blocks[i], ret);
return ret;
diff --git a/boot/espressif/main.c b/boot/espressif/main.c
index 9e1aa07..3f4d5a0 100644
--- a/boot/espressif/main.c
+++ b/boot/espressif/main.c
@@ -12,6 +12,7 @@
#include "bootloader_init.h"
#include "bootloader_utility.h"
#include "bootloader_random.h"
+#include "bootloader_soc.h"
#include "esp_assert.h"
@@ -118,6 +119,21 @@
esp_efuse_init_virtual_mode_in_flash(CONFIG_EFUSE_VIRTUAL_OFFSET, CONFIG_EFUSE_VIRTUAL_SIZE);
#endif
+#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_FLASH_ENC_ENABLED)
+ esp_err_t err;
+#endif
+
+#ifdef CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
+ if (esp_secure_boot_enabled() ^ esp_flash_encrypt_initialized_once()) {
+ BOOT_LOG_ERR("Secure Boot and Flash Encryption cannot be enabled separately, only together (their keys go into one eFuse key block)");
+ FIH_PANIC;
+ }
+
+ if (!esp_secure_boot_enabled() || !esp_flash_encryption_enabled()) {
+ esp_efuse_batch_write_begin();
+ }
+#endif // CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
+
#ifdef CONFIG_SECURE_BOOT
/* Steps 1 (see above for full description):
* 1) Compute digest of the public key.
@@ -132,7 +148,6 @@
} else {
esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
- esp_err_t err;
err = check_and_generate_secure_boot_keys();
if (err != ESP_OK) {
esp_efuse_batch_write_cancel();
@@ -178,7 +193,6 @@
if (!sb_hw_enabled) {
BOOT_LOG_INF("blowing secure boot efuse...");
- esp_err_t err;
err = esp_secure_boot_enable_secure_features();
if (err != ESP_OK) {
esp_efuse_batch_write_cancel();
@@ -195,8 +209,10 @@
assert(esp_efuse_read_field_bit(ESP_EFUSE_SECURE_BOOT_AGGRESSIVE_REVOKE));
#endif
+#ifndef CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
assert(esp_secure_boot_enabled());
BOOT_LOG_INF("Secure boot permanently enabled");
+#endif
}
#endif
@@ -206,17 +222,51 @@
* 5) Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
* 6) Burn EFUSE to enable flash encryption
*/
-
- int rc;
-
BOOT_LOG_INF("Checking flash encryption...");
- bool flash_encryption_enabled = esp_flash_encryption_enabled();
- rc = esp_flash_encrypt_check_and_update();
- if (rc != ESP_OK) {
- BOOT_LOG_ERR("Flash encryption check failed (%d).", rc);
+ bool flash_encryption_enabled = esp_flash_encrypt_state();
+ if (!flash_encryption_enabled) {
+#ifdef CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
+ BOOT_LOG_ERR("flash encryption is not enabled, and SECURE_FLASH_REQUIRE_ALREADY_ENABLED is set, refusing to boot.");
FIH_PANIC;
+#endif // CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
+
+ if (esp_flash_encrypt_is_write_protected(true)) {
+ FIH_PANIC;
+ }
+
+ err = esp_flash_encrypt_init();
+ if (err != ESP_OK) {
+ BOOT_LOG_ERR("Initialization of Flash Encryption key failed (%d)", err);
+ FIH_PANIC;
+ }
}
+ if (!flash_encryption_enabled) {
+ err = esp_flash_encrypt_contents();
+ if (err != ESP_OK) {
+ BOOT_LOG_ERR("Encryption flash contents failed (%d)", err);
+ FIH_PANIC;
+ }
+
+ err = esp_flash_encrypt_enable();
+ if (err != ESP_OK) {
+ BOOT_LOG_ERR("Enabling of Flash encryption failed (%d)", err);
+ FIH_PANIC;
+ }
+ }
+
+#ifdef CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
+ if (!esp_secure_boot_enabled() || !flash_encryption_enabled) {
+ err = esp_efuse_batch_write_commit();
+ if (err != ESP_OK) {
+ BOOT_LOG_ERR("Error programming eFuses (err=0x%x).", err);
+ FIH_PANIC;
+ }
+ assert(esp_secure_boot_enabled());
+ BOOT_LOG_INF("Secure boot permanently enabled");
+ }
+#endif // CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER
+
/* Step 7 (see above for full description):
* 7) Reset system to ensure flash encryption cache resets properly.
*/
@@ -229,6 +279,12 @@
BOOT_LOG_INF("Disabling RNG early entropy source...");
bootloader_random_disable();
+ /* Disable glitch reset after all the security checks are completed.
+ * Glitch detection can be falsely triggered by EMI interference (high RF TX power, etc)
+ * and to avoid such false alarms, disable it.
+ */
+ bootloader_ana_clock_glitch_reset_config(false);
+
#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
/* Multi image independent boot
* Boot on the second processor happens before the image0 boot
diff --git a/boot/espressif/port/esp32c2/bootloader.conf b/boot/espressif/port/esp32c2/bootloader.conf
index 286b1a1..54f797e 100644
--- a/boot/espressif/port/esp32c2/bootloader.conf
+++ b/boot/espressif/port/esp32c2/bootloader.conf
@@ -63,6 +63,12 @@
# using imgtool instead of use the existent sample
# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem
+# Hardware Secure Boot related options
+# CONFIG_SECURE_SIGNED_ON_BOOT=1
+# CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME=1
+# CONFIG_SECURE_BOOT=1
+# CONFIG_SECURE_BOOT_V2_ENABLED=1
+
# Hardware Flash Encryption related options
# CONFIG_SECURE_FLASH_ENC_ENABLED=1
# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
@@ -72,6 +78,10 @@
# CONFIG_SECURE_BOOT_ALLOW_JTAG=1
# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1
+# This option must be also enabled when enabling both Secure Boot
+# and Flash Encryption at same time
+# CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER=1
+
# Options for enabling eFuse emulation in Flash
# CONFIG_EFUSE_VIRTUAL=1
# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1
diff --git a/boot/espressif/port/esp32c3/ld/bootloader.ld b/boot/espressif/port/esp32c3/ld/bootloader.ld
index 65f15cc..747b549 100644
--- a/boot/espressif/port/esp32c3/ld/bootloader.ld
+++ b/boot/espressif/port/esp32c3/ld/bootloader.ld
@@ -13,8 +13,8 @@
MEMORY
{
iram_seg (RWX) : org = 0x403C7000, len = 0x9000
- iram_loader_seg (RWX) : org = 0x403D0000, len = 0x5000
- dram_seg (RW) : org = 0x3FCD5000, len = 0xA000
+ iram_loader_seg (RWX) : org = 0x403D0000, len = 0x5400
+ dram_seg (RW) : org = 0x3FCD5400, len = 0xA000
}
/* Default entry point: */