From 36815fa1bf44742924a32e9e6200609b7cea306f Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 29 Jun 2021 11:22:58 +1000 Subject: [PATCH 1/4] soc: Add SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS flags for esp32s2,s3 Fixes regression in f339b3fc966 --- components/soc/esp32s2/include/soc/soc_caps.h | 1 + components/soc/esp32s3/include/soc/soc_caps.h | 1 + 2 files changed, 2 insertions(+) diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 535c0bba5f..41949515e0 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -54,6 +54,7 @@ #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 #define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1 +#define SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS 1 #define SOC_CACHE_SUPPORT_WRAP 1 /*-------------------------- ADC CAPS ----------------------------------------*/ diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 05e11a847e..49313943a5 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -21,6 +21,7 @@ #define SOC_HMAC_SUPPORTED 0 #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 +#define SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS 1 #define SOC_SDMMC_HOST_SUPPORTED 1 #define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1 From fcd193b02473454960fb61f02fe8ef084b4ce258 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 29 Jun 2021 11:30:40 +1000 Subject: [PATCH 2/4] docs: Use soc_caps instead of chip names for flash encryption docs Clears the way for ESP32-S3 and future chips. --- .../efuse/src/esp_efuse_api_key_esp32xx.c | 2 +- components/efuse/test/test_efuse_keys.c | 6 ++-- components/soc/esp32c3/include/soc/soc_caps.h | 1 + components/soc/esp32s2/include/soc/soc_caps.h | 3 +- components/soc/esp32s3/include/soc/soc_caps.h | 5 +-- docs/en/security/flash-encryption.rst | 36 +++++++++---------- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/components/efuse/src/esp_efuse_api_key_esp32xx.c b/components/efuse/src/esp_efuse_api_key_esp32xx.c index 2b3a085acd..eb745ad769 100644 --- a/components/efuse/src/esp_efuse_api_key_esp32xx.c +++ b/components/efuse/src/esp_efuse_api_key_esp32xx.c @@ -302,7 +302,7 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo ESP_EFUSE_CHK(esp_efuse_write_field_blob(s_table[idx].key, key, key_size_bytes * 8)); ESP_EFUSE_CHK(esp_efuse_set_key_dis_write(block)); if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY || -#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS +#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256 purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || #endif diff --git a/components/efuse/test/test_efuse_keys.c b/components/efuse/test/test_efuse_keys.c index cbc74d71d4..24f3190bed 100644 --- a/components/efuse/test/test_efuse_keys.c +++ b/components/efuse/test/test_efuse_keys.c @@ -62,7 +62,7 @@ static esp_err_t s_check_key(esp_efuse_block_t num_key, void* wr_key) TEST_ASSERT_TRUE(esp_efuse_get_key_dis_write(num_key)); if (purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY || -#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS +#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256 purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 || purpose == ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 || #endif @@ -149,7 +149,7 @@ TEST_CASE("Test 1 esp_efuse_write_key for FPGA", "[efuse]") esp_efuse_purpose_t purpose [] = { ESP_EFUSE_KEY_PURPOSE_USER, ESP_EFUSE_KEY_PURPOSE_RESERVED, -#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS +#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256 ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1, ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2, #else @@ -217,7 +217,7 @@ TEST_CASE("Test esp_efuse_write_keys", "[efuse]") esp_efuse_block_t key_block = EFUSE_BLK_MAX; enum { BLOCKS_NEEDED1 = 2 }; -#ifdef SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS +#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_256 esp_efuse_purpose_t purpose1[BLOCKS_NEEDED1] = { ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1, ESP_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2, diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index eef3d9c157..5b54f55865 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -13,6 +13,7 @@ #define SOC_HMAC_SUPPORTED 1 #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_USB_SERIAL_JTAG_SUPPORTED 1 +#define SOC_FLASH_ENCRYPTION_XTS_AES 1 /*-------------------------- COMMON CAPS ---------------------------------------*/ #define SOC_SUPPORTS_SECURE_DL_MODE 1 diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 41949515e0..b0f55e6db9 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -54,8 +54,9 @@ #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 #define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1 -#define SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS 1 #define SOC_CACHE_SUPPORT_WRAP 1 +#define SOC_FLASH_ENCRYPTION_XTS_AES 1 +#define SOC_FLASH_ENCRYPTION_XTS_AES_256 1 /*-------------------------- ADC CAPS ----------------------------------------*/ #define SOC_ADC_PERIPH_NUM (2) diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 49313943a5..6c62dad022 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -21,9 +21,10 @@ #define SOC_HMAC_SUPPORTED 0 #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3 -#define SOC_EFUSE_SUPPORT_XTS_AES_256_KEYS 1 -#define SOC_SDMMC_HOST_SUPPORTED 1 #define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1 +#define SOC_SDMMC_HOST_SUPPORTED 1 +#define SOC_FLASH_ENCRYPTION_XTS_AES 1 +#define SOC_FLASH_ENCRYPTION_XTS_AES_256 1 /*-------------------------- ADC CAPS ----------------------------------------*/ diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index f04e1712f7..9feb56658e 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -49,7 +49,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF .. Comment: As text in cells of list-table header rows does not wrap, it is necessary to make 0 header rows and apply bold typeface to the first row. Otherwise, the table goes beyond the html page limits on the right. -.. only:: esp32 +.. only:: not SOC_FLASH_ENCRYPTION_XTS_AES .. list-table:: eFuses Used in Flash Encryption :widths: 25 40 10 @@ -78,7 +78,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF - 7 -.. only:: esp32s2 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 .. list-table:: eFuses Used in Flash Encryption :widths: 25 40 10 @@ -100,7 +100,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF - Enables encryption and decryption, when an SPI boot mode is set. Feature is enabled if 1 or 3 bits are set in the eFuse, disabled otherwise. - 3 -.. only:: esp32c3 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES and not SOC_FLASH_ENCRYPTION_XTS_AES_256 .. list-table:: eFuses Used in Flash Encryption :widths: 25 40 10 @@ -134,7 +134,7 @@ Flash Encryption Process Assuming that the eFuse values are in their default states and the firmware bootloader is compiled to support flash encryption, the flash encryption process executes as shown below: -.. only:: esp32 +.. only:: not SOC_FLASH_ENCRYPTION_XTS_AES 1. On the first power-on reset, all data in flash is un-encrypted (plaintext). The ROM bootloader loads the firmware bootloader. @@ -152,7 +152,7 @@ Assuming that the eFuse values are in their default states and the firmware boot 8. The device is then rebooted to start executing the encrypted image. The firmware bootloader calls the flash decryption block to decrypt the flash contents and then loads the decrypted contents into IRAM. -.. only:: esp32s2 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 1. On the first power-on reset, all data in flash is un-encrypted (plaintext). The ROM bootloader loads the firmware bootloader. @@ -170,7 +170,7 @@ Assuming that the eFuse values are in their default states and the firmware boot 8. The device is then rebooted to start executing the encrypted image. The firmware bootloader calls the flash decryption block to decrypt the flash contents and then loads the decrypted contents into IRAM. -.. only:: esp32c3 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES and not SOC_FLASH_ENCRYPTION_XTS_AES_256 1. On the first power-on reset, all data in flash is un-encrypted (plaintext). The ROM bootloader loads the firmware bootloader. @@ -285,7 +285,7 @@ To use a host generated key, take the following steps: 2. Generate a random key by running: -.. only:: esp32s2 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 If :ref:`Size of generated AES-XTS key ` is AES-256 (512-bit key) need to use the `XTS_AES_256_KEY_1` and `XTS_AES_256_KEY_2` purposes. The espsecure does not support 512-bit key, but it is possible to workaround: @@ -305,7 +305,7 @@ To use a host generated key, take the following steps: espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin -.. only:: not esp32s2 +.. only:: not SOC_FLASH_ENCRYPTION_XTS_AES_256 .. code-block:: bash @@ -314,13 +314,13 @@ To use a host generated key, take the following steps: 3. **Before the first encrypted boot**, burn the key into your device's eFuse using the command below. This action can be done **only once**. -.. only:: esp32 +.. only:: not SOC_FLASH_ENCRYPTION_XTS_AES .. code-block:: bash espefuse.py --port PORT burn_key flash_encryption my_flash_encryption_key.bin -.. only:: esp32s2 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 .. code-block:: bash @@ -342,7 +342,7 @@ To use a host generated key, take the following steps: espefuse.py --port PORT burn_key BLOCK+1 my_flash_encryption_key2.bin XTS_AES_256_KEY_2 -.. only:: esp32c3 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES and not SOC_FLASH_ENCRYPTION_XTS_AES_256 .. code-block:: bash @@ -672,7 +672,7 @@ If flash encryption was enabled accidentally, flashing of plaintext data will so For flash encryption in Development mode, encryption can be disabled by burning the ``{IDF_TARGET_CRYPT_CNT}`` eFuse. It can only be done three times per chip by taking the following steps: -.. only:: esp32s2 or esp32c3 +.. only:: not esp32 For flash encryption in Development mode, encryption can be disabled by burning the ``{IDF_TARGET_CRYPT_CNT}`` eFuse. It can only be done one time per chip by taking the following steps: @@ -791,7 +791,7 @@ On the first boot, the flash encryption process burns by default the following e - ``DISABLE_DL_DECRYPT`` which disables transparent flash decryption when running in UART bootloader mode, even if the eFuse ``{IDF_TARGET_CRYPT_CNT}`` is set to enable it in normal operation. - ``DISABLE_DL_CACHE`` which disables the entire MMU flash cache when running in UART bootloader mode. -.. only:: esp32s2 or esp32c3 +.. only:: not esp32 .. list:: @@ -811,7 +811,7 @@ However, before the first boot you can choose to keep any of these features enab espefuse.py --port PORT burn_efuse DISABLE_DL_DECRYPT espefuse.py --port PORT write_protect_efuse DISABLE_DL_ENCRYPT -.. only:: esp32s2 or esp32c3 +.. only:: not esp32 .. code-block:: bash @@ -862,7 +862,7 @@ Technical Details The following sections provide some reference information about the operation of flash encryption. -.. only:: esp32 +.. only:: not SOC_FLASH_ENCRYPTION_XTS_AES .. _flash-encryption-algorithm: @@ -897,13 +897,13 @@ The following sections provide some reference information about the operation of - To see the full flash encryption algorithm implemented in Python, refer to the `_flash_encryption_operation()` function in the ``espsecure.py`` source code. -.. only:: esp32s2 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 .. _flash-encryption-algorithm: Flash Encryption Algorithm ^^^^^^^^^^^^^^^^^^^^^^^^^^ - - {IDF_TARGET_NAME} use the XTS-AES block chiper mode with 256 bit or 512 bit key size for flash encryption. + - {IDF_TARGET_NAME} use the XTS-AES block cipher mode with 256 bit or 512 bit key size for flash encryption. - XTS-AES is a block chiper mode specifically designed for disc encryption and addresses the weaknesses other potential modes (e.g. AES-CTR) have for this use case. A detailed description of the XTS-AES algorithm can be found in `IEEE Std 1619-2007 `_. @@ -911,7 +911,7 @@ The following sections provide some reference information about the operation of - To see the full flash encryption algorithm implemented in Python, refer to the `_flash_encryption_operation()` function in the ``espsecure.py`` source code. -.. only:: esp32c3 +.. only:: SOC_FLASH_ENCRYPTION_XTS_AES and not SOC_FLASH_ENCRYPTION_XTS_AES_256 .. _flash-encryption-algorithm: From 765b75d37bbc8d1152e322ba2ddb5d94f748d3d8 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Tue, 29 Jun 2021 11:31:10 +1000 Subject: [PATCH 3/4] docs: Add description of manual encryption steps Closes https://github.com/espressif/esp-idf/issues/5037 --- docs/en/security/flash-encryption.rst | 57 +++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index 9feb56658e..7834970870 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -373,7 +373,9 @@ Enabling flash encryption will increase the size of bootloader, which might requ This command will write to flash memory unencrypted images: the firmware bootloader, the partition table and applications. Once the flashing is complete, {IDF_TARGET_NAME} will reset. On the next boot, the firmware bootloader encrypts: the firmware bootloader, application partitions and partitions marked as ``encrypted`` then resets. Encrypting in-place can take time, up to a minute for large partitions. After that, the application is decrypted at runtime and executed. -At this stage, if you need to update and re-flash binaries, see :ref:`encrypt-partitions`. +If using Development Mode, then the easiest way to update and re-flash binaries is :ref:`encrypt-partitions`. + +If using Release Mode, then it is possible to pre-encrypt the binaries on the host and then flash them as ciphertext. See :ref:`manual-encryption`. .. _encrypt-partitions: @@ -440,9 +442,9 @@ For subsequent plaintext field updates, use :ref:`OTA scheme ` then you will need to pass the ``--flash_crypt_conf`` argument to ``espsecure.py`` to set the matching value. This will not happen if the device configured flash encryption by itself, but may happen if burning efuses manually to enable flash encryption. + +The command ``espsecure.py decrypt_flash_data`` can be used with the same options (and different input/output files), to decrypt ciphertext flash contents or a previously encrypted file. + Technical Details ----------------- From f62c3036338503671847437c69f40ccfbb0e94fd Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 30 Jun 2021 10:28:27 +1000 Subject: [PATCH 4/4] docs: Explain the 256- and 512- bit keys used for AES-XTS 256 vs 512 --- docs/en/security/flash-encryption.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index 7834970870..e4cb20d3ab 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -63,7 +63,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF - 2 * - ``flash_encryption`` (block1) - AES key storage. - - 256 + - 256 bit key block * - ``FLASH_CRYPT_CONFIG`` - Controls the AES encryption process. - 4 @@ -89,7 +89,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF - **Bit Depth** * - ``BLOCK_KEYN`` - AES key storage. N is between 0 and 5. - - 256 + - One 256 bit key block for XTS_AES_128, Two 256 bit key blocks for XTS_AES_256 (512 bit total) * - ``KEY_PURPOSE_N`` - Controls the purpose of eFuse block ``BLOCK_KEYN``, where N is between 0 and 5. Possible values: ``2`` for ``XTS_AES_256_KEY_1`` , ``3`` for ``XTS_AES_256_KEY_2``, and ``4`` for ``XTS_AES_128_KEY``. Final AES key is derived based on the value of one or two of these purpose eFuses. For a detailed description of the possible combinations, see *{IDF_TARGET_NAME} Technical Reference Manual* > *External Memory Encryption and Decryption (XTS_AES)* [`PDF <{IDF_TARGET_TRM_EN_URL}#extmemencr>`__]. - 4 @@ -111,7 +111,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF - **Bit Depth** * - ``BLOCK_KEYN`` - AES key storage. N is between 0 and 5. - - 256 + - 256 bit key block * - ``KEY_PURPOSE_N`` - Controls the purpose of eFuse block ``BLOCK_KEYN``, where N is between 0 and 5. For flash encryption the only valid value is ``4`` for ``XTS_AES_128_KEY``. - 4 @@ -872,7 +872,7 @@ See :ref:`jtag-debugging-security-features` for more information about using JTA Manually Encrypting Files ^^^^^^^^^^^^^^^^^^^^^^^^^ -Manually encrypting or decrypting files requires the flash encryption key to be pre-burned in efuse (see :ref:`pregenerated-flash-encryption-key`) and a copy to be kept on the host. If the flash encryption is configured in Development Mode then it's not necessary to keep a copy of the key or follow these steps, the simpler :ref:`encrypt-partitions` steps can be used. +Manually encrypting or decrypting files requires the flash encryption key to be pre-burned in eFuse (see :ref:`pregenerated-flash-encryption-key`) and a copy to be kept on the host. If the flash encryption is configured in Development Mode then it's not necessary to keep a copy of the key or follow these steps, the simpler :ref:`encrypt-partitions` steps can be used. The key file should be a single raw binary file (example: ``key.bin``). @@ -904,7 +904,7 @@ The file ``my-app-ciphertext.bin`` can then be flashed to offset 0x10000 using ` .. only:: esp32 - If your ESP32 uses non-default :ref:`FLASH_CRYPT_CONFIG value in efuse ` then you will need to pass the ``--flash_crypt_conf`` argument to ``espsecure.py`` to set the matching value. This will not happen if the device configured flash encryption by itself, but may happen if burning efuses manually to enable flash encryption. + If your ESP32 uses non-default :ref:`FLASH_CRYPT_CONFIG value in eFuse ` then you will need to pass the ``--flash_crypt_conf`` argument to ``espsecure.py`` to set the matching value. This will not happen if the device configured flash encryption by itself, but may happen if burning eFuses manually to enable flash encryption. The command ``espsecure.py decrypt_flash_data`` can be used with the same options (and different input/output files), to decrypt ciphertext flash contents or a previously encrypted file.