From 76291d0095cd0a46a2328a676b260b496ea3f579 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Thu, 16 Mar 2023 16:47:53 +0800 Subject: [PATCH] efuse: Fix load_efuses_from_flash when FE is on esp_efuse_utility_load_efuses_from_flash() read emul_efuse as an encrypted partition, but that is not correct, this partition was never encrypted. Need to read it as not encrypted partition. Fxed the case: If FE is already on then EFUSE VIRT mode can work with it. Closes https://github.com/espressif/esp-idf/issues/10929 --- .../bootloader_flash/src/bootloader_flash.c | 3 ++- components/bootloader_support/src/flash_encrypt.c | 7 ++++--- components/efuse/src/esp_efuse_utility.c | 2 +- components/hal/efuse_hal.c | 13 +++++++++++++ components/hal/include/hal/efuse_hal.h | 9 +++++++++ docs/en/api-reference/system/efuse.rst | 5 +++++ 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index da282577a8..34e993e0bf 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -10,6 +10,7 @@ #include #include "sdkconfig.h" #include "soc/soc_caps.h" +#include "hal/efuse_hal.h" #if CONFIG_IDF_TARGET_ESP32 # include "soc/spi_struct.h" @@ -29,7 +30,7 @@ #include "esp_rom_spiflash.h" #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH -#define ENCRYPTION_IS_VIRTUAL 1 +#define ENCRYPTION_IS_VIRTUAL (!efuse_hal_flash_encryption_enabled()) #else #define ENCRYPTION_IS_VIRTUAL 0 #endif diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index 7e40983ad5..57f4560f4b 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -11,6 +11,7 @@ #include "esp_efuse_table.h" #include "esp_flash_encrypt.h" #include "esp_secure_boot.h" +#include "hal/efuse_hal.h" #if CONFIG_IDF_TARGET_ESP32 #define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT @@ -81,15 +82,14 @@ void esp_flash_encryption_init_checks() */ 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; @@ -100,6 +100,7 @@ bool IRAM_ATTR esp_flash_encryption_enabled(void) flash_crypt_cnt >>= 1; } return enabled; +#endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH } void esp_flash_write_protect_crypt_cnt(void) diff --git a/components/efuse/src/esp_efuse_utility.c b/components/efuse/src/esp_efuse_utility.c index 07798fc5cb..38ca8c12a9 100644 --- a/components/efuse/src/esp_efuse_utility.c +++ b/components/efuse/src/esp_efuse_utility.c @@ -439,7 +439,7 @@ bool esp_efuse_utility_load_efuses_from_flash(void) } uint32_t efuses_in_flash[sizeof(virt_blocks)]; - esp_err_t err = bootloader_flash_read(esp_efuse_flash_offset, &efuses_in_flash, sizeof(efuses_in_flash), true); + esp_err_t err = bootloader_flash_read(esp_efuse_flash_offset, &efuses_in_flash, sizeof(efuses_in_flash), false); if (err != ESP_OK) { ESP_EARLY_LOGE(TAG, "Can not read eFuse partition from flash (err=0x%x)", err); abort(); diff --git a/components/hal/efuse_hal.c b/components/hal/efuse_hal.c index 8bcf30c635..51514ad499 100644 --- a/components/hal/efuse_hal.c +++ b/components/hal/efuse_hal.c @@ -23,3 +23,16 @@ IRAM_ATTR uint32_t efuse_hal_chip_revision(void) { return efuse_hal_get_major_chip_version() * 100 + efuse_hal_get_minor_chip_version(); } + +IRAM_ATTR bool efuse_hal_flash_encryption_enabled(void) +{ + uint32_t flash_crypt_cnt = efuse_ll_get_flash_crypt_cnt(); + bool enabled = false; + while (flash_crypt_cnt) { + if (flash_crypt_cnt & 1) { + enabled = !enabled; + } + flash_crypt_cnt >>= 1; + } + return enabled; +} diff --git a/components/hal/include/hal/efuse_hal.h b/components/hal/include/hal/efuse_hal.h index 2f141b7440..bb11c9ae7b 100644 --- a/components/hal/include/hal/efuse_hal.h +++ b/components/hal/include/hal/efuse_hal.h @@ -26,6 +26,15 @@ void efuse_hal_get_mac(uint8_t *mac); */ uint32_t efuse_hal_chip_revision(void); +/** + * @brief Is flash encryption currently enabled in hardware? + * + * Flash encryption is enabled if the FLASH_CRYPT_CNT efuse has an odd number of bits set. + * + * @return true if flash encryption is enabled. + */ +bool efuse_hal_flash_encryption_enabled(void); + /** * @brief Returns major chip version */ diff --git a/docs/en/api-reference/system/efuse.rst b/docs/en/api-reference/system/efuse.rst index 3e28e20f2b..956675b969 100644 --- a/docs/en/api-reference/system/efuse.rst +++ b/docs/en/api-reference/system/efuse.rst @@ -411,6 +411,11 @@ During startup, the eFuses are copied to RAM. All eFuse operations (read and wri In addition to the :ref:`CONFIG_EFUSE_VIRTUAL` option there is :ref:`CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH` option that adds a feature to keep eFuses in flash memory. To use this mode the partition_table should have the `efuse` partition. partition.csv: ``"efuse_em, data, efuse, , 0x2000,"``. During startup, the eFuses are copied from flash or, in case if flash is empty, from real eFuse to RAM and then update flash. This option allows keeping eFuses after reboots (possible to test secure_boot and flash_encryption features with this option). +Flash Encryption Testing +"""""""""""""""""""""""" + +Flash Encryption (FE) is a hardware feature that requires the physical burning of eFuses: key and FLASH_CRYPT_CNT. If FE is not actually enabled then enabling the :ref:`CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH` option just gives testing possibilities and does not encrypt anything in the flash, even though the logs say encryption happens. The :cpp:func:`bootloader_flash_write` is adapted for this purpose. But if FE is already enabled on the chip and you run an application or bootloader created with the :ref:`CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH` option then the flash encryption/decryption operations will work properly (data are encrypted as it is written into an encrypted flash partition and decrypted when they are read from an encrypted partition). + espefuse.py ^^^^^^^^^^^