diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index b5dca09a20..6c86b14e28 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -1134,6 +1134,44 @@ menu "Security features" If not set, the app does not care if the flash encryption eFuse bit is set or not. + config SECURE_FLASH_PSEUDO_ROUND_FUNC + bool "Permanently enable XTS-AES's pseudo rounds function" + default y + depends on SECURE_FLASH_ENCRYPTION_MODE_RELEASE && SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND + help + If set (default), the bootloader will permanently enable the XTS-AES peripheral's pseudo rounds function. + Note: Enabling this config would burn an efuse. + + choice SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH + prompt "Strength of the pseudo rounds function" + depends on SECURE_FLASH_PSEUDO_ROUND_FUNC + default SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_LOW + help + The strength of the pseudo rounds functions can be configured to low, medium and high, + each denoting the values that would be stored in the efuses field. + By default the value to set to low. + You can configure the strength of the pseudo rounds functions according to your use cases, + for example, increasing the strength would provide higher security but would slow down the + flash encryption/decryption operations. + For more info regarding the performance impact, please checkout the pseudo round function section of the + security guide documentation. + + config SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_LOW + bool "Low" + + config SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_MEDIUM + bool "Medium" + + config SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_HIGH + bool "High" + endchoice + + config SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH + int + default 1 if SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_LOW + default 2 if SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_MEDIUM + default 3 if SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH_HIGH + config SECURE_ROM_DL_MODE_ENABLED bool default y if SOC_SUPPORTS_SECURE_DL_MODE && !SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT diff --git a/components/bootloader_support/src/esp32h2/flash_encryption_secure_features.c b/components/bootloader_support/src/esp32h2/flash_encryption_secure_features.c index f1a6d2aef9..d4b063a4d6 100644 --- a/components/bootloader_support/src/esp32h2/flash_encryption_secure_features.c +++ b/components/bootloader_support/src/esp32h2/flash_encryption_secure_features.c @@ -1,15 +1,18 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include "esp_flash_encrypt.h" #include "esp_secure_boot.h" #include "esp_efuse.h" #include "esp_efuse_table.h" #include "esp_log.h" +#include "hal/spi_flash_encrypted_ll.h" +#include "soc/soc_caps.h" #include "sdkconfig.h" static __attribute__((unused)) const char *TAG = "flash_encrypt"; @@ -33,6 +36,14 @@ esp_err_t esp_flash_encryption_enable_secure_features(void) esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT); +#if defined(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE) && defined(SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND) + if (spi_flash_encrypt_ll_is_pseudo_rounds_function_supported()) { + ESP_LOGI(TAG, "Enable XTS-AES pseudo rounds function..."); + uint8_t xts_pseudo_level = CONFIG_SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH; + esp_efuse_write_field_blob(ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL, &xts_pseudo_level, ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL[0]->bit_count); + } +#endif + #if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS) // This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot // otherwise the Flash Encryption key cannot be read protected diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index da57e4189a..381f17ed40 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,9 @@ #include "esp_flash_encrypt.h" #include "esp_secure_boot.h" #include "hal/efuse_hal.h" +#include "hal/spi_flash_encrypted_ll.h" +#include "hal/spi_flash_encrypt_hal.h" +#include "soc/soc_caps.h" #if CONFIG_IDF_TARGET_ESP32 #define CRYPT_CNT ESP_EFUSE_FLASH_CRYPT_CNT @@ -207,6 +210,13 @@ void esp_flash_encryption_set_release_mode(void) #endif // CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128_DERIVED #endif // !CONFIG_IDF_TARGET_ESP32 +#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND + if (spi_flash_encrypt_ll_is_pseudo_rounds_function_supported()) { + uint8_t xts_pseudo_level = ESP_XTS_AES_PSEUDO_ROUNDS_LOW; + esp_efuse_write_field_blob(ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL, &xts_pseudo_level, ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL[0]->bit_count); + } +#endif + #ifdef CONFIG_IDF_TARGET_ESP32 esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_DIS_CACHE); #else @@ -468,6 +478,17 @@ bool esp_flash_encryption_cfg_verify_release_mode(void) } result &= secure; +#if SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND + if (spi_flash_encrypt_ll_is_pseudo_rounds_function_supported()) { + uint8_t xts_pseudo_level = 0; + esp_efuse_read_field_blob(ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL, &xts_pseudo_level, ESP_EFUSE_XTS_DPA_PSEUDO_LEVEL[0]->bit_count); + if (!xts_pseudo_level) { + result &= false; + ESP_LOGW(TAG, "Not enabled XTS-AES pseudo rounds function (set XTS_DPA_PSEUDO_LEVEL->1 or more)"); + } + } +#endif + return result; } #endif // not CONFIG_IDF_TARGET_ESP32 diff --git a/components/hal/esp32/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32/include/hal/spi_flash_encrypted_ll.h index 682be30815..7827c5cab9 100644 --- a/components/hal/esp32/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32/include/hal/spi_flash_encrypted_ll.h @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include "soc/dport_reg.h" #include "soc/flash_encryption_reg.h" diff --git a/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h index 8d59c99148..7c8b10376e 100644 --- a/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include @@ -24,7 +25,7 @@ extern "C" { #endif -/// Choose type of chip you want to encrypt manully +/// Choose type of chip you want to encrypt manually typedef enum { FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip. @@ -51,7 +52,7 @@ static inline void spi_flash_encrypt_ll_disable(void) } /** - * Choose type of chip you want to encrypt manully + * Choose type of chip you want to encrypt manually * * @param type The type of chip to be encrypted * diff --git a/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h index 8857e1f915..7c8b10376e 100644 --- a/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include @@ -24,7 +25,7 @@ extern "C" { #endif -/// Choose type of chip you want to encrypt manully +/// Choose type of chip you want to encrypt manually typedef enum { FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip. @@ -51,7 +52,7 @@ static inline void spi_flash_encrypt_ll_disable(void) } /** - * Choose type of chip you want to encrypt manully + * Choose type of chip you want to encrypt manually * * @param type The type of chip to be encrypted * diff --git a/components/hal/esp32c5/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c5/include/hal/spi_flash_encrypted_ll.h index f0e9235e3d..1953fc9256 100644 --- a/components/hal/esp32c5/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c5/include/hal/spi_flash_encrypted_ll.h @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include diff --git a/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h index 20c303344a..debef0835f 100644 --- a/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include @@ -24,7 +25,7 @@ extern "C" { #endif -/// Choose type of chip you want to encrypt manully +/// Choose type of chip you want to encrypt manually typedef enum { FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip. @@ -51,7 +52,7 @@ static inline void spi_flash_encrypt_ll_disable(void) } /** - * Choose type of chip you want to encrypt manully + * Choose type of chip you want to encrypt manually * * @param type The type of chip to be encrypted * diff --git a/components/hal/esp32c61/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c61/include/hal/spi_flash_encrypted_ll.h index 4192f40a65..7f9bf3499f 100644 --- a/components/hal/esp32c61/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c61/include/hal/spi_flash_encrypted_ll.h @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include diff --git a/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h index cb6cab28a3..e4d10407ba 100644 --- a/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include diff --git a/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h index 9c3304832b..948e964db3 100644 --- a/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include @@ -24,7 +25,7 @@ extern "C" { #endif -/// Choose type of chip you want to encrypt manully +/// Choose type of chip you want to encrypt manually typedef enum { FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip. @@ -51,7 +52,7 @@ static inline void spi_flash_encrypt_ll_disable(void) } /** - * Choose type of chip you want to encrypt manully + * Choose type of chip you want to encrypt manually * * @param type The type of chip to be encrypted * diff --git a/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h index 529fb99007..93e369d2fd 100644 --- a/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include @@ -24,7 +25,7 @@ extern "C" { #endif -/// Choose type of chip you want to encrypt manully +/// Choose type of chip you want to encrypt manually typedef enum { FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip. @@ -61,7 +62,7 @@ static inline void spi_flash_encrypt_ll_disable(void) } /** - * Choose type of chip you want to encrypt manully + * Choose type of chip you want to encrypt manually * * @param type The type of chip to be encrypted * diff --git a/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h index dae3528dd9..d5b168c55e 100644 --- a/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,7 @@ ******************************************************************************/ // The Lowlevel layer for SPI Flash Encryption. +#pragma once #include #include @@ -24,7 +25,7 @@ extern "C" { #endif -/// Choose type of chip you want to encrypt manully +/// Choose type of chip you want to encrypt manually typedef enum { FLASH_ENCRYPTION_MANU = 0, ///!< Manually encrypt the flash chip. @@ -51,7 +52,7 @@ static inline void spi_flash_encrypt_ll_disable(void) } /** - * Choose type of chip you want to encrypt manully + * Choose type of chip you want to encrypt manually * * @param type The type of chip to be encrypted * diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index b5c07b2b76..b6b2c071df 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -533,6 +533,7 @@ To use this mode, take the following steps: :esp32: - :ref:`Select UART ROM download mode (Permanently disabled (recommended)) ` (Note that this option is only available when :ref:`CONFIG_ESP32_REV_MIN` is set to 3 (ESP32 V3).) The default choice is to keep UART ROM download mode enabled, however it is recommended to permanently disable this mode to reduce the options available to an attacker. :not esp32: - :ref:`Select Release mode ` (Note that once Release mode is selected, the ``EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT`` eFuse bit will be burned to disable flash encryption hardware in ROM Download Mode.) :not esp32: - :ref:`Select UART ROM download mode (Permanently switch to Secure mode (recommended)) `. This is the default option, and is recommended. It is also possible to change this configuration setting to permanently disable UART ROM download mode, if this mode is not needed. + :SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND: - :ref:`Select enable XTS-AES's pseudo rounds function `. This option is selected by default and its strength is configured to level low considering the performance impact on the flash encryption/decryption operations. Please refer to :ref:`xts-aes-pseudo-round-func` for more information regarding the performance impact per security level. - :ref:`Select the appropriate bootloader log verbosity ` - Save the configuration and exit. @@ -1119,3 +1120,36 @@ The following sections provide some reference information about the operation of - The flash encryption key is stored in ``BLOCK_KEY0`` eFuse and, by default, is protected from further writes or software readout. - To see the full flash encryption algorithm implemented in Python, refer to the `_flash_encryption_operation()` function in the ``espsecure.py`` source code. + +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND + + Protection Against Side-Channel Attacks + --------------------------------------- + + .. _xts-aes-pseudo-round-func: + + Pseudo-Round Function + ^^^^^^^^^^^^^^^^^^^^^ + + {IDF_TARGET_NAME} incorporates a pseudo-round function in the XTS-AES peripheral, thus enabling the peripheral to randomly insert pseudo-rounds before and after the original operation rounds and also generate a pseudo key to perform these dummy operations. + These operations do not alter the original result, but they increase the complexity to perform side channel analysis attacks by randomizing the power profile. + + :ref:`CONFIG_SECURE_FLASH_PSEUDO_ROUND_FUNC_STRENGTH` can be used to select the strength of the pseudo-round function. Increasing the strength improves the security provided, but would slow down the XTS-AES operations. + + .. list-table:: Performance impact on XTS-AES operations per strength level + :widths: 10 10 + :header-rows: 1 + :align: center + + * - **Strength** + - **Performance Impact** + * - Low + - < 0.5 % + * - Medium + - 6.2 % + * - High + - 18 % + + You can configure the strength of the pseudo rounds functions according to your use cases. For example, increasing the strength would provide higher security but would slow down the flash encryption/decryption operations. + + Considering the above performance impact, ESP-IDF by-default enables low strength configuration for the pseudo-round function for minimal performance impact. diff --git a/docs/en/security/security-features-enablement-workflows.rst b/docs/en/security/security-features-enablement-workflows.rst index 973c7305b1..76a7547e6c 100644 --- a/docs/en/security/security-features-enablement-workflows.rst +++ b/docs/en/security/security-features-enablement-workflows.rst @@ -250,6 +250,7 @@ In this case all the eFuses related to Flash Encryption are written with help of :SOC_EFUSE_DIS_PAD_JTAG: - ``DIS_PAD_JTAG``: Disable JTAG permanently :not esp32: - ``DIS_DOWNLOAD_MANUAL_ENCRYPT``: Disable UART bootloader encryption access :SOC_EFUSE_DIS_DOWNLOAD_MSPI: - ``DIS_DOWNLOAD_MSPI``: Disable the MSPI access in download mode + :SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND: - ``XTS_DPA_PSEUDO_LEVEL``: Enable the pseudo rounds function of the XTS-AES peripheral. The value to be burned in the efuse can be 1, 2 or 3, denoting the security level. These values correspond to low, medium, high level respectively. By default ESP-IDF's bootloader configures the value of this efuse to 1 (low) while enabling flash encryption release mode during boot-up. The respective eFuses can be burned by running: