mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
docs(key-manager): Add Key-Manager peripheral related documentation
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -48,7 +48,7 @@ typedef enum {
|
||||
ESP_KEY_MGR_PSRAM_XTS_AES_KEY, /* PSRAM XTS-AES key */
|
||||
} esp_key_mgr_key_type_t;
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Key Manager key usage type
|
||||
*/
|
||||
typedef enum {
|
||||
@@ -112,30 +112,37 @@ typedef enum {
|
||||
ESP_KEY_MGR_FORCE_USE_KM_DS_KEY = 3,
|
||||
} esp_key_mgr_force_use_km_key_t;
|
||||
|
||||
// store huk info, occupy 96 words
|
||||
/**
|
||||
* @brief HUK info structure, stores HUK recovery information
|
||||
*/
|
||||
typedef struct PACKED_ATTR {
|
||||
#define HUK_INFO_LEN 660
|
||||
uint8_t info[HUK_INFO_LEN];
|
||||
uint32_t crc;
|
||||
uint8_t info[HUK_INFO_LEN]; /*!< HUK info data */
|
||||
uint32_t crc; /*!< CRC of the HUK info */
|
||||
} esp_key_mgr_huk_info_t;
|
||||
|
||||
// store key info, occupy 512 bits
|
||||
/**
|
||||
* @brief Key info structure, stores key recovery information (512 bits)
|
||||
*/
|
||||
typedef struct PACKED_ATTR {
|
||||
#define KEY_INFO_LEN 64
|
||||
uint8_t info[KEY_INFO_LEN];
|
||||
uint32_t crc;
|
||||
uint8_t info[KEY_INFO_LEN]; /*!< Key info data */
|
||||
uint32_t crc; /*!< CRC of the key info */
|
||||
} esp_key_mgr_key_info_t;
|
||||
|
||||
/**
|
||||
* @brief Key recovery info structure containing all data needed to recover a deployed key
|
||||
*/
|
||||
typedef struct WORD_ALIGNED_ATTR PACKED_ATTR {
|
||||
#define KEY_HUK_SECTOR_MAGIC 0xDEA5CE5A
|
||||
uint32_t magic;
|
||||
uint32_t version; // for backward compatibility
|
||||
uint8_t key_type;
|
||||
uint8_t key_len;
|
||||
uint8_t key_deployment_mode;
|
||||
uint8_t reserved[13];
|
||||
esp_key_mgr_huk_info_t huk_info;
|
||||
esp_key_mgr_key_info_t key_info[2]; // at most 2 key info (XTS-512_1 and XTS-512_2), at least use 1
|
||||
uint32_t magic; /*!< Magic number for validation */
|
||||
uint32_t version; /*!< Version for backward compatibility */
|
||||
uint8_t key_type; /*!< Type of the deployed key */
|
||||
uint8_t key_len; /*!< Length of the deployed key */
|
||||
uint8_t key_deployment_mode; /*!< Deployment mode used for the key */
|
||||
uint8_t reserved[13]; /*!< Reserved for future use */
|
||||
esp_key_mgr_huk_info_t huk_info; /*!< HUK recovery info */
|
||||
esp_key_mgr_key_info_t key_info[2]; /*!< Key info (up to 2 entries for XTS-AES-256) */
|
||||
} esp_key_mgr_key_recovery_info_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -33,36 +33,48 @@ extern "C" {
|
||||
#define KEY_MGR_ECDH0_INFO_SIZE 64
|
||||
#define KEY_MGR_PLAINTEXT_KEY_SIZE 32
|
||||
|
||||
/**
|
||||
* @brief Configuration for deploying a key in AES mode
|
||||
*/
|
||||
typedef struct {
|
||||
esp_key_mgr_key_type_t key_type;
|
||||
esp_key_mgr_key_len_t key_len;
|
||||
bool use_pre_generated_huk_info;
|
||||
bool use_pre_generated_sw_init_key;
|
||||
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info;
|
||||
WORD_ALIGNED_ATTR uint8_t sw_init_key[KEY_MGR_SW_INIT_KEY_SIZE];
|
||||
WORD_ALIGNED_ATTR uint8_t k2_info[KEY_MGR_K2_INFO_SIZE];
|
||||
WORD_ALIGNED_ATTR uint8_t k1_encrypted[2][KEY_MGR_K1_ENCRYPTED_SIZE];
|
||||
esp_key_mgr_key_type_t key_type; /*!< Type of key to deploy */
|
||||
esp_key_mgr_key_len_t key_len; /*!< Length of the key */
|
||||
bool use_pre_generated_huk_info; /*!< Use pre-generated HUK info if true */
|
||||
bool use_pre_generated_sw_init_key; /*!< Use pre-generated software init key if true */
|
||||
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info; /*!< HUK recovery info */
|
||||
WORD_ALIGNED_ATTR uint8_t sw_init_key[KEY_MGR_SW_INIT_KEY_SIZE]; /*!< Software init key */
|
||||
WORD_ALIGNED_ATTR uint8_t k2_info[KEY_MGR_K2_INFO_SIZE]; /*!< K2 info for AES deployment */
|
||||
WORD_ALIGNED_ATTR uint8_t k1_encrypted[2][KEY_MGR_K1_ENCRYPTED_SIZE]; /*!< Encrypted K1 key data */
|
||||
} esp_key_mgr_aes_key_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration for deploying a key in ECDH0 mode
|
||||
*/
|
||||
typedef struct {
|
||||
esp_key_mgr_key_type_t key_type;
|
||||
esp_key_mgr_key_len_t key_len;
|
||||
bool use_pre_generated_huk_info;
|
||||
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info;
|
||||
WORD_ALIGNED_ATTR uint8_t k1_G[2][KEY_MGR_ECDH0_INFO_SIZE];
|
||||
esp_key_mgr_key_type_t key_type; /*!< Type of key to deploy */
|
||||
esp_key_mgr_key_len_t key_len; /*!< Length of the key */
|
||||
bool use_pre_generated_huk_info; /*!< Use pre-generated HUK info if true */
|
||||
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info; /*!< HUK recovery info */
|
||||
WORD_ALIGNED_ATTR uint8_t k1_G[2][KEY_MGR_ECDH0_INFO_SIZE]; /*!< K1*G points for ECDH0 deployment */
|
||||
} esp_key_mgr_ecdh0_key_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration for deploying a key in Random mode
|
||||
*/
|
||||
typedef struct {
|
||||
esp_key_mgr_key_type_t key_type;
|
||||
esp_key_mgr_key_len_t key_len;
|
||||
bool use_pre_generated_huk_info;
|
||||
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info;
|
||||
esp_key_mgr_key_type_t key_type; /*!< Type of key to deploy */
|
||||
esp_key_mgr_key_len_t key_len; /*!< Length of the key */
|
||||
bool use_pre_generated_huk_info; /*!< Use pre-generated HUK info if true */
|
||||
WORD_ALIGNED_ATTR esp_key_mgr_huk_info_t huk_info; /*!< HUK recovery info */
|
||||
} esp_key_mgr_random_key_config_t;
|
||||
|
||||
/**
|
||||
* @brief ECDH0 key info generated during ECDH0 deployment
|
||||
*/
|
||||
typedef struct {
|
||||
esp_key_mgr_key_type_t key_type;
|
||||
esp_key_mgr_key_len_t key_len;
|
||||
WORD_ALIGNED_ATTR uint8_t k2_G[2][KEY_MGR_ECDH0_INFO_SIZE];
|
||||
esp_key_mgr_key_type_t key_type; /*!< Type of key */
|
||||
esp_key_mgr_key_len_t key_len; /*!< Length of the key */
|
||||
WORD_ALIGNED_ATTR uint8_t k2_G[2][KEY_MGR_ECDH0_INFO_SIZE]; /*!< K2*G points from ECDH0 deployment */
|
||||
} esp_key_mgr_ecdh0_info_t;
|
||||
|
||||
/**
|
||||
@@ -74,63 +86,66 @@ void key_mgr_wait_for_state(esp_key_mgr_state_t state);
|
||||
|
||||
/**
|
||||
* @brief Deploy key in AES deployment mode
|
||||
* @input
|
||||
* key_config(input) AES key configuration
|
||||
* key_info(output) A writable struct of esp_key_mgr_key_info_t type.
|
||||
* The recovery information for the the deployed key shall be stored here (Make sure that the memory is valid during the deployment process).
|
||||
*
|
||||
* @param[in] key_config AES key configuration
|
||||
* @param[out] key_info A writable struct of esp_key_mgr_key_recovery_info_t type.
|
||||
* The recovery information for the deployed key shall be stored here.
|
||||
* @return
|
||||
* ESP_OK for success
|
||||
* ESP_FAIL/relevant error code for failure
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL or relevant error code on failure
|
||||
*/
|
||||
esp_err_t esp_key_mgr_deploy_key_in_aes_mode(const esp_key_mgr_aes_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info);
|
||||
|
||||
/**
|
||||
* @brief Deploy key in ECDH0 deployment mode
|
||||
* @input
|
||||
* key_config(input) ECDH0 key configuration
|
||||
* key_info(output) A writable struct of esp_key_mgr_key_info_t type. The recovery key info for the deployed key shall be stored here (Make sure that the memory is valid during the deployment process).
|
||||
* ecdh0_key_info A writable struct of esp_key_mgr_ecdh0_info_t. The ecdh0 info to recover the actual key shall be stored here.
|
||||
*
|
||||
* @param[in] key_config ECDH0 key configuration
|
||||
* @param[out] key_info A writable struct of esp_key_mgr_key_recovery_info_t type.
|
||||
* The recovery key info for the deployed key shall be stored here.
|
||||
* @param[out] ecdh0_key_info A writable struct of esp_key_mgr_ecdh0_info_t type.
|
||||
* The ECDH0 info to recover the actual key shall be stored here.
|
||||
* @return
|
||||
* ESP_OK for success
|
||||
* ESP_FAIL/relevant error code for failure
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL or relevant error code on failure
|
||||
*/
|
||||
esp_err_t esp_key_mgr_deploy_key_in_ecdh0_mode(const esp_key_mgr_ecdh0_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info, esp_key_mgr_ecdh0_info_t *ecdh0_key_info);
|
||||
|
||||
/**
|
||||
* @brief Deploy key in Random deployment mode
|
||||
* @input
|
||||
* key_config(input) Random key configuration
|
||||
* key_info(output) A writable struct of esp_key_mgr_key_info_t type. The recovery key info for the deployed key shall be stored here (Make sure that the memory is valid during the deployment process).
|
||||
*
|
||||
* @param[in] key_config Random key configuration
|
||||
* @param[out] key_info A writable struct of esp_key_mgr_key_recovery_info_t type.
|
||||
* The recovery key info for the deployed key shall be stored here.
|
||||
* @return
|
||||
* ESP_OK for success
|
||||
* ESP_FAIL/relevant error code for failure
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL or relevant error code on failure
|
||||
*/
|
||||
esp_err_t esp_key_mgr_deploy_key_in_random_mode(const esp_key_mgr_random_key_config_t *key_config, esp_key_mgr_key_recovery_info_t *key_info);
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Recover and Activate a key from the given key info
|
||||
*
|
||||
* @note
|
||||
* Once a key of particular type is activated through Key Manager,
|
||||
* then a different key of the same type cannot be activated at the same time.
|
||||
* This key must be deactivated first through a call to esp_key_mgr_deactivate_key()
|
||||
* before activating other key of the same type
|
||||
* @input
|
||||
* key_info The key info required to recover the key
|
||||
* @note Once a key of particular type is activated through Key Manager,
|
||||
* then a different key of the same type cannot be activated at the same time.
|
||||
* This key must be deactivated first through a call to esp_key_mgr_deactivate_key()
|
||||
* before activating other key of the same type.
|
||||
*
|
||||
* @param[in] key_recovery_info The key recovery info required to recover the key
|
||||
* @return
|
||||
* ESP_OK for success
|
||||
* ESP_FAIL/relevant error code for failure
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL or relevant error code on failure
|
||||
*/
|
||||
esp_err_t esp_key_mgr_activate_key(esp_key_mgr_key_recovery_info_t *key_recovery_info);
|
||||
|
||||
/*
|
||||
* @brief De-activate a key from the given key info
|
||||
* The key which is de-activated can no longer be used for any operation
|
||||
* @input
|
||||
* key_info The key info required to recover the key
|
||||
/**
|
||||
* @brief De-activate a key of the given type
|
||||
*
|
||||
* The key which is de-activated can no longer be used for any operation.
|
||||
*
|
||||
* @param[in] key_type The type of the key to deactivate
|
||||
* @return
|
||||
* ESP_OK for success
|
||||
* ESP_FAIL/relevant error code for failure
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL or relevant error code on failure
|
||||
*/
|
||||
esp_err_t esp_key_mgr_deactivate_key(esp_key_mgr_key_type_t key_type);
|
||||
|
||||
|
||||
@@ -368,6 +368,7 @@ conditional_include_dict = {
|
||||
'SOC_HMAC_SUPPORTED': ['api-reference/peripherals/hmac.rst'],
|
||||
'SOC_GDMA_SUPPORT_CRC': ['api-reference/peripherals/async_crc.rst'],
|
||||
'SOC_ASYNC_MEMCPY_SUPPORTED': ['api-reference/peripherals/async_memcpy.rst'],
|
||||
'SOC_KEY_MANAGER_SUPPORTED': ['api-reference/peripherals/key_manager.rst'],
|
||||
'CONFIG_IDF_TARGET_ARCH_XTENSA': XTENSA_DOCS,
|
||||
'CONFIG_IDF_TARGET_ARCH_RISCV': RISCV_DOCS,
|
||||
'SOC_TEMP_SENSOR_SUPPORTED': TEMP_SENSOR_DOCS,
|
||||
|
||||
@@ -126,6 +126,7 @@ api-reference/peripherals/sdspi_share.rst
|
||||
api-reference/peripherals/ana_cmpr.rst
|
||||
api-reference/peripherals/adc_continuous.rst
|
||||
api-reference/peripherals/hmac.rst
|
||||
api-reference/peripherals/key_manager.rst
|
||||
api-reference/peripherals/sdspi_host.rst
|
||||
api-reference/peripherals/vad.rst
|
||||
api-reference/peripherals/i2s.rst
|
||||
|
||||
@@ -383,6 +383,8 @@ PREDEFINED = \
|
||||
configTASKLIST_INCLUDE_COREID=1 \
|
||||
configUSE_SB_COMPLETED_CALLBACK=1 \
|
||||
PRIVILEGED_FUNCTION= \
|
||||
PACKED_ATTR= \
|
||||
WORD_ALIGNED_ATTR= \
|
||||
"ESP_EVENT_DECLARE_BASE(x)=extern esp_event_base_t x"
|
||||
|
||||
## Do not complain about not having dot
|
||||
|
||||
@@ -22,4 +22,6 @@ INPUT += \
|
||||
$(PROJECT_PATH)/components/esp_tee/include/esp_tee.h \
|
||||
$(PROJECT_PATH)/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h \
|
||||
$(PROJECT_PATH)/components/esp_tee/subproject/components/tee_ota_ops/include/esp_tee_ota_ops.h \
|
||||
$(PROJECT_PATH)/components/esp_security/include/esp_key_mgr.h \
|
||||
$(PROJECT_PATH)/components/esp_hal_security/include/hal/key_mgr_types.h \
|
||||
$(PROJECT_PATH)/components/mbedtls/port/include/psa/initial_attestation.h \
|
||||
|
||||
@@ -53,4 +53,6 @@ INPUT += \
|
||||
$(PROJECT_PATH)/components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h \
|
||||
$(PROJECT_PATH)/components/ulp/lp_core/shared/include/ulp_lp_core_lp_uart_shared.h \
|
||||
$(PROJECT_PATH)/components/ulp/lp_core/shared/include/ulp_lp_core_lp_vad_shared.h \
|
||||
$(PROJECT_PATH)/components/ulp/ulp_common/include/ulp_common.h
|
||||
$(PROJECT_PATH)/components/ulp/ulp_common/include/ulp_common.h \
|
||||
$(PROJECT_PATH)/components/esp_security/include/esp_key_mgr.h \
|
||||
$(PROJECT_PATH)/components/esp_hal_security/include/hal/key_mgr_types.h
|
||||
|
||||
@@ -3,7 +3,13 @@ Digital Signature (DS)
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
The Digital Signature (DS) module provides hardware acceleration of signing messages based on RSA. It uses pre-encrypted parameters to calculate a signature. The parameters are encrypted using HMAC as a key-derivation function. In turn, the HMAC uses eFuses as the input key. The whole process happens in hardware so that neither the decryption key for the RSA parameters nor the input key for the HMAC key derivation function can be seen by the software while calculating the signature.
|
||||
The Digital Signature (DS) module provides hardware acceleration of signing messages based on RSA. It uses pre-encrypted parameters to calculate a signature. The parameters are encrypted using HMAC as a key-derivation function. In turn, the HMAC uses eFuses as the input key.
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
On {IDF_TARGET_NAME}, the Digital Signature (DS) module can also use a key stored in the Key Manager instead of an eFuse key block. The AES encryption key can be directly deployed in the Key Manager with the type :cpp:enumerator:`ESP_KEY_MGR_DS_KEY`. Refer to :ref:`key-manager` for more details.
|
||||
|
||||
The whole process happens in hardware so that neither the decryption key for the RSA parameters nor the input key for the HMAC key derivation function can be seen by the software while calculating the signature.
|
||||
|
||||
For more detailed information on the hardware involved in the signature calculation and the registers used, see **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__].
|
||||
|
||||
@@ -112,7 +118,11 @@ Example for SSL Mutual Authentication Using DS
|
||||
|
||||
The SSL mutual authentication example that previously lived under ``examples/protocols/mqtt/ssl_ds`` is now shipped with the standalone `espressif/mqtt <https://components.espressif.com/components/espressif/mqtt>`__ component. Follow the component documentation to fetch the SSL DS example and build it together with ESP-MQTT. The example continues to use ``mqtt_client`` (implemented by ESP-MQTT) to connect to ``test.mosquitto.org`` over mutual-authenticated TLS, with the TLS portion handled by ESP-TLS.
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
In case both the :cpp:member:`esp_ds_data_ctx_t::efuse_key_id` and :cpp:member:`esp_rsa_ds_opaque_key_t::key_recovery_info` are set, the ESP-DS PSA driver prefers using the Key Manager-based DS key over the eFuse-based DS key.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/esp_ds.inc
|
||||
.. include-build-file:: inc/psa_crypto_driver_esp_rsa_ds_contexts.inc
|
||||
|
||||
@@ -24,7 +24,14 @@ Supported Features
|
||||
ECDSA on {IDF_TARGET_NAME}
|
||||
--------------------------
|
||||
|
||||
On {IDF_TARGET_NAME}, the ECDSA module works with a secret key burnt into an eFuse block. This eFuse key is made completely inaccessible (default mode) for any resources outside the cryptographic modules, thus avoiding key leakage.
|
||||
On {IDF_TARGET_NAME}, the ECDSA module works with a secret key burnt into an eFuse block.
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
On {IDF_TARGET_NAME}, the ECDSA module also supports storing a secret key in the Key Manager. Refer to :ref:`key-manager` for more details.
|
||||
|
||||
This key is made completely inaccessible (default mode) for any resources outside the cryptographic modules, thus avoiding key leakage.
|
||||
|
||||
|
||||
ECDSA Key Storage
|
||||
^^^^^^^^^^^^^^^^^
|
||||
@@ -53,6 +60,8 @@ ECDSA Key Storage
|
||||
|
||||
ECDSA key can be programmed externally through ``idf.py`` script. Here is an example of how to program the ECDSA key:
|
||||
|
||||
Using eFuses to store the ECDSA key:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
idf.py efuse-burn-key <BLOCK_NUM> </path/to/ecdsa_private_key.pem> ECDSA_KEY
|
||||
@@ -69,9 +78,18 @@ ECDSA key can be programmed externally through ``idf.py`` script. Here is an exa
|
||||
|
||||
Six physical eFuse blocks can be used as keys for the ECDSA module: block 4 ~ block 9. E.g., for block 4 (which is the first key block) , the argument should be ``BLOCK_KEY0``.
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
Using the Key Manager to store the ECDSA key:
|
||||
|
||||
ECDSA private keys can be stored in the Key Manager. Refer to :ref:`key-manager` for more details.
|
||||
|
||||
Deploy an ECDSA key into the Key Manager and store the generated Key Recovery info in the flash memory for persistent keys.
|
||||
|
||||
Alternatively the ECDSA key can also be programmed through the application running on the target.
|
||||
|
||||
Using eFuses to store the ECDSA key:
|
||||
|
||||
Following code snippet uses :cpp:func:`esp_efuse_write_key` to set physical key block 0 in the eFuse with key purpose as :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -26,7 +26,13 @@ However, the HMAC itself is not bound to this use case. It can also be used for
|
||||
HMAC on {IDF_TARGET_NAME}
|
||||
-----------------------------
|
||||
|
||||
On {IDF_TARGET_NAME}, the HMAC module works with a secret key burnt into the eFuses. This eFuse key can be made completely inaccessible for any resources outside the cryptographic modules, thus avoiding key leakage.
|
||||
On {IDF_TARGET_NAME}, the HMAC module works with a secret key burnt into the eFuses.
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
On {IDF_TARGET_NAME}, the HMAC module also supports storing a secret key in the Key Manager. Refer to :ref:`key-manager` for more details.
|
||||
|
||||
This key can be made completely inaccessible for any resources outside the cryptographic modules, thus avoiding key leakage.
|
||||
|
||||
Furthermore, {IDF_TARGET_NAME} has three different application scenarios for its HMAC module:
|
||||
|
||||
@@ -142,6 +148,8 @@ Application Outline
|
||||
|
||||
The following code is an outline of how to set an eFuse key and then use it to calculate an HMAC for software usage.
|
||||
|
||||
Using eFuses to store the HMAC key:
|
||||
|
||||
We use ``esp_efuse_write_key`` to set physical key block 4 in the eFuse for the HMAC module together with its purpose. ``ESP_EFUSE_KEY_PURPOSE_HMAC_UP`` (8) means that this key can only be used for HMAC generation for software usage:
|
||||
|
||||
.. code-block:: c
|
||||
@@ -162,6 +170,8 @@ We use ``esp_efuse_write_key`` to set physical key block 4 in the eFuse for the
|
||||
|
||||
Now we can calculate an HMAC for software usage with the saved key through the PSA Crypto API.
|
||||
|
||||
Using an eFuse-based HMAC key:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include "psa/crypto.h"
|
||||
@@ -181,9 +191,8 @@ Now we can calculate an HMAC for software usage with the saved key through the P
|
||||
psa_set_key_bits(&attributes, 256);
|
||||
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE);
|
||||
|
||||
// Create opaque key reference
|
||||
// Create opaque key reference for eFuse-based key
|
||||
esp_hmac_opaque_key_t opaque_key = {
|
||||
.use_km_key = false,
|
||||
.efuse_key_id = HMAC_KEY4,
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ Peripherals API
|
||||
:SOC_I3C_MASTER_SUPPORTED: i3c_master
|
||||
:SOC_ISP_SUPPORTED: isp
|
||||
:SOC_JPEG_CODEC_SUPPORTED: jpeg
|
||||
:SOC_KEY_MANAGER_SUPPORTED: key_manager
|
||||
lcd/index
|
||||
:SOC_GP_LDO_SUPPORTED: ldo_regulator
|
||||
ledc
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
.. _key-manager:
|
||||
|
||||
Key Manager
|
||||
===========
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
The {IDF_TARGET_NAME}'s Key Manager peripheral provides hardware-assisted **key deployment and recovery** for cryptographic keys. It allows cryptographic keys to be provisioned and used without storing plaintext key material in flash, RAM, or eFuses.
|
||||
The Key Manager is intended for applications that require secure handling of long-term cryptographic keys.
|
||||
|
||||
.. only:: esp32p4
|
||||
|
||||
.. note::
|
||||
|
||||
The Key Manager peripheral is only supported on ESP32-P4 chip revision >= v3.0.
|
||||
|
||||
.. only:: esp32c5
|
||||
|
||||
.. note::
|
||||
|
||||
The Key Manager peripheral is only supported on ESP32-C5 chip revision >= v1.2.
|
||||
|
||||
Key Manager provides the following properties:
|
||||
|
||||
- **Device uniqueness**
|
||||
|
||||
Keys are cryptographically bound to a Hardware Unique Key (HUK) that is unique to each chip.
|
||||
|
||||
- **No plaintext key storage**
|
||||
|
||||
Key material is never exposed in software accessible memory.
|
||||
|
||||
- **Flexible key lifecycle**
|
||||
|
||||
Keys can be deployed, recovered, or replaced by a newer key without reprogramming the eFuses for each key.
|
||||
|
||||
- **Resistance to physical extraction**
|
||||
|
||||
Reading flash or eFuses contents would not reveal usable key material.
|
||||
|
||||
Hardware Unique Key (HUK)
|
||||
-------------------------
|
||||
|
||||
The Hardware Unique Key (HUK) is a device-specific unique key generated entirely in hardware HUK peripheral. It is generated using SRAM Physical Unclonable Function (PUF) and is reconstructed using the HUK recovery info stored in the key recovery info of a Key Manager deployed key. See *{IDF_TARGET_NAME} Technical Reference Manual* > *Chapter Key Manager* [`PDF <{IDF_TARGET_TRM_EN_URL}>`__] > *HUK Generator* for more details about the HUK peripheral.
|
||||
|
||||
The HUK acts as the root of trust for all keys deployed through the Key Manager.
|
||||
|
||||
Key deployment and key recovery
|
||||
-------------------------------
|
||||
|
||||
The Key Manager operates in two distinct phases:
|
||||
|
||||
- **Key deployment**
|
||||
|
||||
A cryptographic key is generated or securely introduced into the chip and it gets bound to the HUK. This step is usually performed during manufacturing, first boot up or when generating transient or persistent keys during the application runtime.
|
||||
|
||||
- **Key recovery**
|
||||
|
||||
On subsequent boots, a Key Manager-deployed persistent key is restored using the previously generated key recovery information, without exposing the key value.
|
||||
|
||||
During deployment, the Key Manager generates a data structure referred to as :cpp:type:`esp_key_mgr_key_recovery_info_t`. In case of persistent keys, the applications must store this data in non-volatile storage (for example, flash) in order to recover the key on later boots.
|
||||
|
||||
Supported key types
|
||||
-------------------
|
||||
|
||||
The Key Manager can manage keys for the following key types:
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY: - ECDSA
|
||||
:SOC_KEY_MANAGER_FE_KEY_DEPLOY: - Flash encryption (XTS-AES)
|
||||
:SOC_KEY_MANAGER_HMAC_KEY_DEPLOY: - HMAC
|
||||
:SOC_KEY_MANAGER_DS_KEY_DEPLOY: - Digital signature peripherals
|
||||
:SOC_KEY_MANAGER_FE_KEY_DEPLOY: - PSRAM encryption
|
||||
|
||||
Each key is associated with a :cpp:type:`esp_key_mgr_key_purpose_t`, which defines how the key can be used by hardware peripherals.
|
||||
|
||||
Key deployment modes
|
||||
--------------------
|
||||
|
||||
The Key Manager provides multiple key deployment modes to support different provisioning and security requirements.
|
||||
|
||||
Random Deploy Mode
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In this mode, the Key Manager generates a random private key internally.
|
||||
|
||||
- The key value is never known to the application software
|
||||
- No external key material is required
|
||||
- Intended for use cases where the key does not need to be backed up or exported
|
||||
|
||||
AES Deploy Mode
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
In this mode, a user-specified private key is securely deployed.
|
||||
|
||||
- The key is encrypted before being transmitted to the chip
|
||||
- Auxiliary key material is used to protect the deployment process
|
||||
- Intended for factory provisioning scenarios where the key value must be predefined
|
||||
|
||||
ECDH0 Deploy Mode
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
In this mode, a private key is negotiated using Elliptic Curve Diffie-Hellman (ECDH).
|
||||
|
||||
- The final private key is never transmitted
|
||||
- The deployment process can occur over an untrusted channel
|
||||
- Intended for high-security provisioning environments
|
||||
|
||||
For detailed information various deployment modes, see *{IDF_TARGET_NAME} Technical Reference Manual* > *Chapter Key Manager* [`PDF <{IDF_TARGET_TRM_EN_URL}>`__] > *Key Manager*.
|
||||
|
||||
.. ECDH1 Deploy Mode
|
||||
.. ~~~~~~~~~~~~~~~~~
|
||||
..
|
||||
.. This mode is similar to ECDH0 Deploy Mode, with additional flexibility for manufacturing workflows.
|
||||
..
|
||||
.. - Supports negotiated key deployment using auxiliary recovery data
|
||||
.. - Allows updating deployed keys by replacing auxiliary information
|
||||
.. - Intended for large-scale manufacturing with controlled trust assumptions
|
||||
|
||||
Typical workflows
|
||||
-----------------
|
||||
|
||||
First Boot or Manufacturing
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A typical provisioning flow includes:
|
||||
|
||||
1. Generating the Hardware Unique Key (HUK)
|
||||
2. Deploying required cryptographic keys using an appropriate deployment mode
|
||||
3. Storing the generated ``key_recovery_info`` in non-volatile storage
|
||||
4. Locking relevant security configuration eFuses, if required
|
||||
|
||||
This process is usually performed once per device.
|
||||
|
||||
Normal Boot
|
||||
^^^^^^^^^^^
|
||||
|
||||
During a normal boot:
|
||||
|
||||
1. The application provides the previously generated and stored ``key_recovery_info`` of a Key Manager-deployed key
|
||||
2. The HUK is reconstructed automatically by hardware
|
||||
3. The Key Manager recovers the deployed key internally
|
||||
4. Cryptographic peripherals can use the recovered key
|
||||
|
||||
Security considerations
|
||||
-----------------------
|
||||
|
||||
Applications using the Key Manager should consider the following:
|
||||
|
||||
- Protect the ``key_recovery_info`` of a Key Manager-deployed key against unauthorized modification or loss
|
||||
- Lock Key Manager's security-related eFuses after successful key deployment to prevent re-deployment of a key of the same type
|
||||
- Avoid deploying new XTS-AES keys when Flash Encryption is already enabled unless explicitly intended
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/esp_key_mgr.inc
|
||||
.. include-build-file:: inc/key_mgr_types.inc
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
An example demonstrating key deployment using the Key Manager and using the deployed key to perform signing operations is available at:
|
||||
|
||||
See :example:`security/key_manager` for the example.
|
||||
|
||||
This example shows how to:
|
||||
|
||||
- Initialize the Key Manager
|
||||
- Deploy keys using the AES deployment mode
|
||||
- Uses the PSA interface to perform signing operations using the Key Manager deployed key
|
||||
|
||||
@@ -66,68 +66,72 @@
|
||||
|
||||
------
|
||||
|
||||
.. first_boot_enc_km
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ESP-ROM:esp32c5-eco3-20250704
|
||||
Build:Jul 4 2025
|
||||
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
|
||||
SPI mode:DIO, clock div:1
|
||||
load:0x40855820,len:0x3a60
|
||||
load:0x4084bba0,len:0xdf4
|
||||
load:0x4084e5a0,len:0x566c
|
||||
entry 0x4084bbaa
|
||||
I (23) boot: ESP-IDF v6.0-dev-3140-ge16a2fb13ad-dirt 2nd stage bootloader
|
||||
I (24) boot: compile time Oct 27 2025 15:35:09
|
||||
I (67) boot: chip revision: v1.1
|
||||
I (70) boot: efuse block revision: v0.3
|
||||
I (88) boot.esp32c5: SPI Speed : 80MHz
|
||||
I (92) boot.esp32c5: SPI Mode : DIO
|
||||
I (96) boot.esp32c5: SPI Flash Size : 2MB
|
||||
I (103) boot: Enabling RNG early entropy source...
|
||||
I (138) boot: Partition Table:
|
||||
I (141) boot: ## Label Usage Type ST Offset Length
|
||||
I (154) boot: 0 nvs WiFi data 01 02 0000e000 00006000
|
||||
I (168) boot: 1 phy_init RF data 01 01 00014000 00001000
|
||||
I (182) boot: 2 factory factory app 00 00 00020000 00100000
|
||||
I (189) boot: End of partition table
|
||||
I (283) esp_image: segment 0: paddr=00020020 vaddr=42070020 size=32f1ch (208668) map
|
||||
I (377) esp_image: segment 1: paddr=00052f44 vaddr=40800000 size=0a2a4h ( 41636) load
|
||||
I (445) esp_image: segment 2: paddr=0005d1f0 vaddr=4080a300 size=02ccch ( 11468) load
|
||||
I (512) esp_image: segment 3: paddr=0005fec4 vaddr=00000000 size=00154h ( 340)
|
||||
I (580) esp_image: segment 4: paddr=00060020 vaddr=42000020 size=63804h (407556) map
|
||||
I (761) boot: Loaded app from partition at offset 0x20000
|
||||
I (764) boot: Checking flash encryption...
|
||||
I (788) efuse: Batch mode of writing fields is enabled
|
||||
I (807) flash_encrypt: Deploying new flash encryption key using Key Manager
|
||||
W (898) flash_encrypt: Not disabling UART bootloader encryption
|
||||
I (904) flash_encrypt: Disable UART bootloader cache...
|
||||
W (917) flash_encrypt: Not disabling JTAG - SECURITY COMPROMISED
|
||||
I (930) efuse: BURN BLOCK0
|
||||
I (935) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (938) efuse: Batch mode. Prepared fields are committed
|
||||
I (1028) esp_image: segment 0: paddr=00002020 vaddr=40855820 size=03a60h ( 14944)
|
||||
I (1096) esp_image: segment 1: paddr=00005a88 vaddr=4084bba0 size=00df4h ( 3572)
|
||||
I (1165) esp_image: segment 2: paddr=00006884 vaddr=4084e5a0 size=0566ch ( 22124)
|
||||
I (1508) flash_encrypt: bootloader encrypted successfully
|
||||
I (1535) flash_encrypt: partition table encrypted and loaded successfully
|
||||
I (1616) esp_image: segment 0: paddr=00020020 vaddr=42070020 size=32f1ch (208668) map
|
||||
I (1711) esp_image: segment 1: paddr=00052f44 vaddr=40800000 size=0a2a4h ( 41636)
|
||||
I (1779) esp_image: segment 2: paddr=0005d1f0 vaddr=4080a300 size=02ccch ( 11468)
|
||||
I (1847) esp_image: segment 3: paddr=0005fec4 vaddr=00000000 size=00154h ( 340)
|
||||
I (1916) esp_image: segment 4: paddr=00060020 vaddr=42000020 size=63804h (407556) map
|
||||
I (2096) flash_encrypt: Encrypting partition 2 at offset 0x20000 (length 0xa3850)...
|
||||
I (5652) flash_encrypt: Done encrypting
|
||||
I (5667) efuse: BURN BLOCK0
|
||||
I (5671) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (5675) flash_encrypt: Flash encryption completed
|
||||
I (5679) boot: Resetting with flash encryption enabled...
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
.. already_en_enc
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
rst:0x1 (POWERON),boot:0x3d (SPI_FAST_FLASH_BOOT)
|
||||
SPI mode:DIO, clock div:2
|
||||
load:0x40855c10,len:0x2be8
|
||||
load:0x4084c7a0,len:0x6f8
|
||||
load:0x4084e9a0,len:0x418c
|
||||
entry 0x4084c804
|
||||
I (32) boot: ESP-IDF v5.3-dev-3860-g5d36288649 2nd stage bootloader
|
||||
I (33) boot: compile time May 7 2024 17:24:43
|
||||
I (34) boot: chip revision: v0.0
|
||||
I (37) boot.esp32c5: SPI Speed : 40MHz
|
||||
I (42) boot.esp32c5: SPI Mode : DIO
|
||||
I (46) boot.esp32c5: SPI Flash Size : 2MB
|
||||
I (51) boot: Enabling RNG early entropy source...
|
||||
I (64) boot: Partition Table:
|
||||
I (67) boot: ## Label Usage Type ST Offset Length
|
||||
I (74) boot: 0 nvs WiFi data 01 02 0000e000 00006000
|
||||
I (82) boot: 1 storage Unknown data 01 ff 00014000 00001000
|
||||
I (89) boot: 2 factory factory app 00 00 00020000 00100000
|
||||
I (97) boot: 3 nvs_key NVS keys 01 04 00120000 00001000
|
||||
I (104) boot: 4 custom_nvs WiFi data 01 02 00121000 00006000
|
||||
I (113) boot: End of partition table
|
||||
I (116) esp_image: segment 0: paddr=00020020 vaddr=42010020 size=095c4h ( 38340) map
|
||||
I (169) esp_image: segment 1: paddr=000295ec vaddr=40800000 size=06a2ch ( 27180) load
|
||||
I (197) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=0f4d4h ( 62676) map
|
||||
I (256) esp_image: segment 3: paddr=0003f4fc vaddr=40806a2c size=00b78h ( 2936) load
|
||||
I (261) esp_image: segment 4: paddr=0004007c vaddr=408075b0 size=00d18h ( 3352) load
|
||||
I (269) boot: Loaded app from partition at offset 0x20000
|
||||
I (270) boot: Checking flash encryption...
|
||||
I (273) efuse: Batch mode of writing fields is enabled
|
||||
I (278) flash_encrypt: Generating new flash encryption key...
|
||||
I (295) efuse: Writing EFUSE_BLK_KEY0 with purpose 4
|
||||
W (300) flash_encrypt: Not disabling UART bootloader encryption
|
||||
I (305) flash_encrypt: Disable JTAG...
|
||||
I (312) efuse: BURN BLOCK4
|
||||
I (317) efuse: BURN BLOCK4 - OK (write block == read block)
|
||||
I (319) efuse: BURN BLOCK0
|
||||
I (325) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (330) efuse: Batch mode. Prepared fields are committed
|
||||
I (335) esp_image: segment 0: paddr=00002020 vaddr=40855c10 size=02be8h ( 11240)
|
||||
I (353) esp_image: segment 1: paddr=00004c10 vaddr=4084c7a0 size=006f8h ( 1784)
|
||||
I (356) esp_image: segment 2: paddr=00005310 vaddr=4084e9a0 size=0418ch ( 16780)
|
||||
I (1131) flash_encrypt: bootloader encrypted successfully
|
||||
I (1229) flash_encrypt: partition table encrypted and loaded successfully
|
||||
I (1230) flash_encrypt: Encrypting partition 1 at offset 0x14000 (length 0x1000)...
|
||||
I (1325) flash_encrypt: Done encrypting
|
||||
I (1325) esp_image: segment 0: paddr=00020020 vaddr=42010020 size=095c4h ( 38340) map
|
||||
I (1362) esp_image: segment 1: paddr=000295ec vaddr=40800000 size=06a2ch ( 27180)
|
||||
I (1389) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=0f4d4h ( 62676) map
|
||||
I (1448) esp_image: segment 3: paddr=0003f4fc vaddr=40806a2c size=00b78h ( 2936)
|
||||
I (1453) esp_image: segment 4: paddr=0004007c vaddr=408075b0 size=00d18h ( 3352)
|
||||
I (1458) flash_encrypt: Encrypting partition 2 at offset 0x20000 (length 0x100000)...
|
||||
I (24332) flash_encrypt: Done encrypting
|
||||
I (24332) flash_encrypt: Encrypting partition 3 at offset 0x120000 (length 0x1000)...
|
||||
I (24422) flash_encrypt: Done encrypting
|
||||
I (24423) efuse: BURN BLOCK0
|
||||
I (24425) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (24427) flash_encrypt: Flash encryption completed
|
||||
I (24431) boot: Resetting with flash encryption enabled...
|
||||
ESP-ROM:esp32c5-20240329
|
||||
Build:Mar 29 2024
|
||||
rst:0x3 (RTC_SW_HPSYS),boot:0x3d (SPI_FAST_FLASH_BOOT)
|
||||
@@ -193,3 +197,79 @@
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
.. already_en_enc_km
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ESP-ROM:esp32c5-eco3-20250704
|
||||
Build:Jul 4 2025
|
||||
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
|
||||
use sector0 for km info
|
||||
use KM derived key
|
||||
SPI mode:DIO, clock div:1
|
||||
load:0x40855820,len:0x3a94
|
||||
load:0x4084bba0,len:0xd84
|
||||
load:0x4084e5a0,len:0x5670
|
||||
entry 0x4084bbaa
|
||||
I (27) boot: ESP-IDF v6.0-dev-3139-gb813f413096-dirt 2nd stage bootloader
|
||||
I (28) boot: compile time Oct 27 2025 18:14:49
|
||||
W (39) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (53) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (67) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (80) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (94) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (108) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
I (116) boot: chip revision: v1.1
|
||||
I (119) boot: efuse block revision: v0.3
|
||||
I (137) boot.esp32c5: SPI Speed : 80MHz
|
||||
I (141) boot.esp32c5: SPI Mode : DIO
|
||||
I (145) boot.esp32c5: SPI Flash Size : 2MB
|
||||
I (149) boot: Enabling RNG early entropy source...
|
||||
W (163) MMU: mmu_ll_write_entry mmu_id=0, entry_id=0, mmu_val=0x00000000, target=1
|
||||
I (191) boot: Partition Table:
|
||||
I (194) boot: ## Label Usage Type ST Offset Length
|
||||
I (208) boot: 0 nvs WiFi data 01 02 0000e000 00006000
|
||||
I (222) boot: 1 phy_init RF data 01 01 00014000 00001000
|
||||
I (235) boot: 2 factory factory app 00 00 00020000 00100000
|
||||
I (242) boot: End of partition table
|
||||
I (396) esp_image: segment 0: paddr=00020020 vaddr=42070020 size=32f1ch (208668) map
|
||||
I (539) esp_image: segment 1: paddr=00052f44 vaddr=40800000 size=0a2a4h ( 41636) load
|
||||
I (629) esp_image: segment 2: paddr=0005d1f0 vaddr=4080a300 size=02ccch ( 11468) load
|
||||
I (719) esp_image: segment 3: paddr=0005fec4 vaddr=00000000 size=00154h ( 340)
|
||||
I (816) esp_image: segment 4: paddr=00060020 vaddr=42000020 size=6378ch (407436) map
|
||||
I (1114) boot: Loaded app from partition at offset 0x20000
|
||||
I (1116) boot: Checking flash encryption...
|
||||
I (1133) flash_encrypt: flash encryption is enabled (1 plaintext flashes left)
|
||||
I (1140) boot: Disabling RNG early entropy source...
|
||||
I (1301) MSPI Timing: Enter flash timing tuning
|
||||
I (1434) cpu_start: Unicore app
|
||||
I (1468) cpu_start: GPIO 12 and 11 are used as console UART I/O pins
|
||||
I (1479) cpu_start: Pro cpu start user code
|
||||
I (1483) cpu_start: cpu freq: 240000000 Hz
|
||||
I (1493) app_init: Application information:
|
||||
I (1496) app_init: Project name: mbedtls_test
|
||||
I (1501) app_init: App version: qa-test-esp32c61-master-2025070
|
||||
I (1507) app_init: Compile time: Oct 27 2025 15:56:18
|
||||
I (1512) app_init: ELF file SHA256: c5f7f520c...
|
||||
I (1517) app_init: ESP-IDF: v6.0-dev-3140-ge16a2fb13ad-dirt
|
||||
I (1528) efuse_init: Min chip rev: v1.0
|
||||
I (1532) efuse_init: Max chip rev: v1.99
|
||||
I (1536) efuse_init: Chip rev: v1.1
|
||||
I (1669) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (1680) heap_init: At 4080FCB0 len 0004C8F0 (306 KiB): RAM
|
||||
I (1685) heap_init: At 4085C5A0 len 00002F58 (11 KiB): RAM
|
||||
I (1695) heap_init: At 50000000 len 00003FE8 (15 KiB): RTCRAM
|
||||
I (1800) spi_flash: detected chip: generic
|
||||
I (1804) spi_flash: flash io: dio
|
||||
W (1807) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
W (1833) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)
|
||||
I (1867) sleep_gpio: Configure to isolate all GPIO pins in sleep state
|
||||
I (1873) sleep_gpio: Enable automatic switching of GPIO sleep configuration
|
||||
I (1926) main_task: Started on CPU0
|
||||
I (1926) main_task: Calling app_main()
|
||||
I (1936) main_task: Returned from app_main()
|
||||
|
||||
|
||||
------
|
||||
|
||||
@@ -70,6 +70,72 @@
|
||||
|
||||
------
|
||||
|
||||
.. first_boot_enc_km
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ESP-ROM:esp32p4-eco5-20250430
|
||||
Build:Apr 30 2025
|
||||
rst:0x17 (CHIP_USB_UART_RESET),boot:0xc (SPI_FAST_FLASH_BOOT)
|
||||
Core0 Saved PC:0x4fc0130e
|
||||
Core1 Saved PC:0x4fc05fa4
|
||||
SPI mode:DIO, clock div:1
|
||||
load:0x4ffb6240,len:0x3870
|
||||
load:0x4ffac2c0,len:0x179c
|
||||
load:0x4ffaefc0,len:0x4ed8
|
||||
entry 0x4ffac2ca
|
||||
I (38) boot: ESP-IDF v6.0-dev-2918-g6629f96afca-dirt 2nd stage bootloader
|
||||
I (38) boot: compile time Oct 14 2025 08:50:07
|
||||
I (39) boot: Multicore bootloader
|
||||
I (85) boot: chip revision: v3.0
|
||||
I (88) boot: efuse block revision: v1.0
|
||||
I (106) boot.esp32p4: SPI Speed : 80MHz
|
||||
I (110) boot.esp32p4: SPI Mode : DIO
|
||||
I (114) boot.esp32p4: SPI Flash Size : 2MB
|
||||
I (121) boot: Enabling RNG early entropy source...
|
||||
I (156) boot: Partition Table:
|
||||
I (159) boot: ## Label Usage Type ST Offset Length
|
||||
I (173) boot: 0 factory factory app 00 00 00010000 00150000
|
||||
I (187) boot: 1 storage Unknown data 01 81 00160000 00050000
|
||||
I (194) boot: End of partition table
|
||||
I (287) esp_image: segment 0: paddr=00010020 vaddr=40030020 size=0d1e8h ( 53736) map
|
||||
I (355) esp_image: segment 1: paddr=0001d210 vaddr=30100000 size=00044h ( 68) load
|
||||
I (423) esp_image: segment 2: paddr=0001d25c vaddr=4ff20000 size=02dbch ( 11708) load
|
||||
I (491) esp_image: segment 3: paddr=00020020 vaddr=40000020 size=21834h (137268) map
|
||||
I (567) esp_image: segment 4: paddr=0004185c vaddr=4ff22dbc size=094e8h ( 38120) load
|
||||
I (635) esp_image: segment 5: paddr=0004ad4c vaddr=4ff2c300 size=044ech ( 17644) load
|
||||
I (750) boot: Loaded app from partition at offset 0x10000
|
||||
I (752) boot: Checking flash encryption...
|
||||
I (777) efuse: Batch mode of writing fields is enabled
|
||||
I (796) flash_encrypt: Deploying new flash encryption key using Key Manager
|
||||
W (933) flash_encrypt: Not disabling UART bootloader encryption
|
||||
I (939) flash_encrypt: Disable UART bootloader cache...
|
||||
W (952) flash_encrypt: Not disabling JTAG - SECURITY COMPROMISED
|
||||
I (965) efuse: BURN BLOCK0
|
||||
I (970) efuse: BURN BLOCK0 - OK (write block == read block)
|
||||
I (973) efuse: Batch mode. Prepared fields are committed
|
||||
I (1063) esp_image: segment 0: paddr=00002020 vaddr=4ffb6240 size=03870h ( 14448)
|
||||
I (1132) esp_image: segment 1: paddr=00005898 vaddr=4ffac2c0 size=0179ch ( 6044)
|
||||
I (1200) esp_image: segment 2: paddr=0000703c vaddr=4ffaefc0 size=04ed8h ( 20184)
|
||||
I (1725) flash_encrypt: bootloader encrypted successfully
|
||||
I (1769) flash_encrypt: partition table encrypted and loaded successfully
|
||||
I (1851) esp_image: segment 0: paddr=00010020 vaddr=40030020 size=0d1e8h ( 53736) map
|
||||
I (1919) esp_image: segment 1: paddr=0001d210 vaddr=30100000 size=00044h ( 68)
|
||||
I (1988) esp_image: segment 2: paddr=0001d25c vaddr=4ff20000 size=02dbch ( 11708)
|
||||
I (2056) esp_image: segment 3: paddr=00020020 vaddr=40000020 size=21834h (137268) map
|
||||
I (2133) esp_image: segment 4: paddr=0004185c vaddr=4ff22dbc size=094e8h ( 38120)
|
||||
I (2202) esp_image: segment 5: paddr=0004ad4c vaddr=4ff2c300 size=044ech ( 17644)
|
||||
I (2315) flash_encrypt: Encrypting partition 0 at offset 0x10000 (length 0x3f260)...
|
||||
I (4978) flash_encrypt: Done encrypting
|
||||
I (4992) efuse: BURN BLOCK0
|
||||
I (4997) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (5001) flash_encrypt: Flash encryption completed
|
||||
I (5005) boot: Resetting with flash encryption enabled...
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
.. already_en_enc
|
||||
|
||||
.. code-block:: none
|
||||
@@ -152,3 +218,77 @@
|
||||
I (595) main_task: Returned from app_main()
|
||||
|
||||
------
|
||||
|
||||
|
||||
.. already_en_enc_km
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ESP-ROM:esp32p4-eco5-20250430
|
||||
Build:Apr 30 2025
|
||||
rst:0x3 (SW_SYS_RESET),boot:0xc (SPI_FAST_FLASH_BOOT)
|
||||
Core0 Saved PC:0x4ffb0910
|
||||
Core1 Saved PC:0x4fc05fa4
|
||||
SPI mode:DIO, clock div:1
|
||||
load:0x4ffb6240,len:0x3870
|
||||
load:0x4ffac2c0,len:0x179c
|
||||
load:0x4ffaefc0,len:0x4ed8
|
||||
entry 0x4ffac2ca
|
||||
I (37) boot: ESP-IDF v6.0-dev-2918-g6629f96afca-dirt 2nd stage bootloader
|
||||
I (38) boot: compile time Oct 14 2025 08:50:07
|
||||
I (38) boot: Multicore bootloader
|
||||
I (84) boot: chip revision: v3.0
|
||||
I (87) boot: efuse block revision: v1.0
|
||||
I (106) boot.esp32p4: SPI Speed : 80MHz
|
||||
I (110) boot.esp32p4: SPI Mode : DIO
|
||||
I (113) boot.esp32p4: SPI Flash Size : 2MB
|
||||
I (121) boot: Enabling RNG early entropy source...
|
||||
I (155) boot: Partition Table:
|
||||
I (158) boot: ## Label Usage Type ST Offset Length
|
||||
I (172) boot: 0 factory factory app 00 00 00010000 00150000
|
||||
I (186) boot: 1 storage Unknown data 01 81 00160000 00050000
|
||||
I (193) boot: End of partition table
|
||||
I (287) esp_image: segment 0: paddr=00010020 vaddr=40030020 size=0d1e8h ( 53736) map
|
||||
I (355) esp_image: segment 1: paddr=0001d210 vaddr=30100000 size=00044h ( 68) load
|
||||
I (422) esp_image: segment 2: paddr=0001d25c vaddr=4ff20000 size=02dbch ( 11708) load
|
||||
I (491) esp_image: segment 3: paddr=00020020 vaddr=40000020 size=21834h (137268) map
|
||||
I (567) esp_image: segment 4: paddr=0004185c vaddr=4ff22dbc size=094e8h ( 38120) load
|
||||
I (635) esp_image: segment 5: paddr=0004ad4c vaddr=4ff2c300 size=044ech ( 17644) load
|
||||
I (750) boot: Loaded app from partition at offset 0x10000
|
||||
I (752) boot: Checking flash encryption...
|
||||
I (769) flash_encrypt: flash encryption is enabled (1 plaintext flashes left)
|
||||
I (776) boot: Disabling RNG early entropy source...
|
||||
W (847) pmu_pvt: blk_version is less than 2, pvt auto dbias init not supported in efuse.
|
||||
I (855) cpu_start: Multicore app
|
||||
I (890) cpu_start: GPIO 38 and 37 are used as console UART I/O pins
|
||||
I (901) cpu_start: Pro cpu start user code
|
||||
I (905) cpu_start: cpu freq: 400000000 Hz
|
||||
I (914) app_init: Application information:
|
||||
I (918) app_init: Project name: crypto_test
|
||||
I (922) app_init: App version: qa-test-esp32c61-master-2025070
|
||||
I (928) app_init: Compile time: Oct 14 2025 08:50:07
|
||||
I (933) app_init: ELF file SHA256: 847005dd4...
|
||||
I (938) app_init: ESP-IDF: v6.0-dev-2918-g6629f96afca-dirt
|
||||
I (949) efuse_init: Min chip rev: v3.0
|
||||
I (953) efuse_init: Max chip rev: v3.99
|
||||
I (957) efuse_init: Chip rev: v3.0
|
||||
I (1126) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (1137) heap_init: At 4FF33B20 len 000874A0 (541 KiB): RAM
|
||||
I (1143) heap_init: At 4FFBAFC0 len 00004BF0 (18 KiB): RAM
|
||||
I (1153) heap_init: At 50108080 len 00007F80 (31 KiB): RTCRAM
|
||||
I (1163) heap_init: At 30100044 len 00001FBC (7 KiB): TCM
|
||||
I (1261) spi_flash: detected chip: gd
|
||||
I (1264) spi_flash: flash io: dio
|
||||
W (1267) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
W (1293) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)
|
||||
I (1357) main_task: Started on CPU0
|
||||
I (1407) main_task: Calling app_main()
|
||||
I (1407) main_task: Returned from app_main()
|
||||
|
||||
Example to check Flash Encryption status
|
||||
This is esp32p4 chip with 2 CPU core(s), WiFi, silicon revision v0.0, 2MB external flash
|
||||
FLASH_CRYPT_CNT eFuse value is 1
|
||||
Flash encryption feature is enabled in DEVELOPMENT mode
|
||||
|
||||
|
||||
------
|
||||
|
||||
@@ -93,7 +93,35 @@ The flash encryption operation is controlled by various eFuses available on {IDF
|
||||
- 7
|
||||
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 and SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
.. list-table:: eFuses Used in Flash Encryption
|
||||
:widths: 25 40 10
|
||||
:header-rows: 0
|
||||
|
||||
* - **eFuse**
|
||||
- **Description**
|
||||
- **Bit Depth**
|
||||
* - ``BLOCK_KEYN``
|
||||
- AES key storage. N is between 0 and 5. When using a Key Manager-based key, this eFuse is not used.
|
||||
- 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>`__]. When enabling Flash Encryption using a Key Manager-based key, this eFuse is not used.
|
||||
- 4
|
||||
* - ``KM_XTS_KEY_LENGTH_256``
|
||||
- When enabling Flash Encryption using a Key Manager-based key, this eFuse is used to control the length of the XTS-AES key. Set this eFuse to 1 to use a 128-bit key, and to 0 to use a 256-bit key. This efuses field is unused when enabling Flash Encryption using a eFuses-based key.
|
||||
- 1
|
||||
* - ``FORCE_USE_KEY_MANAGER_KEY``
|
||||
- When enabling Flash Encryption using a Key Manager-based key, this eFuse is used to force the Key Manager to use the XTS-AES key. Set the bit 1 of this eFuse to use the Key Manager-based key. This efuses field is unused when enabling Flash Encryption using a eFuses-based key.
|
||||
- 1
|
||||
* - ``DIS_DOWNLOAD_MANUAL_ENCRYPT``
|
||||
- If set, disables flash encryption when in download bootmodes.
|
||||
- 1
|
||||
* - ``{IDF_TARGET_CRYPT_CNT}``
|
||||
- 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:: SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
.. list-table:: eFuses Used in Flash Encryption
|
||||
:widths: 25 40 10
|
||||
@@ -115,7 +143,35 @@ 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:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK and SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
.. list-table:: eFuses Used in Flash Encryption
|
||||
:widths: 25 40 10
|
||||
:header-rows: 0
|
||||
|
||||
* - **eFuse**
|
||||
- **Description**
|
||||
- **Bit Depth**
|
||||
* - ``BLOCK_KEYN``
|
||||
- AES key storage. N is between 0 and 5. When using a Key Manager-based key, this eFuse is not used.
|
||||
- 256 bit key block.
|
||||
* - ``KEY_PURPOSE_N``
|
||||
- Control 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``. When enabling Flash Encryption using a Key Manager-based key, this eFuse is not used.
|
||||
- 4
|
||||
* - ``KM_XTS_KEY_LENGTH_256``
|
||||
- When enabling Flash Encryption using a Key Manager-based key, this eFuse is used to control the length of the XTS-AES key. Set this eFuse to 1 to use a 128-bit key, and to 0 to use a 256-bit key. This efuses field is unused when enabling Flash Encryption using a eFuses-based key.
|
||||
- 1
|
||||
* - ``FORCE_USE_KEY_MANAGER_KEY``
|
||||
- When enabling Flash Encryption using a Key Manager-based key, this eFuse is used to force the Key Manager to use the XTS-AES key. Set the bit 1 of this eFuse to use the Key Manager-based key. This efuses field is unused when enabling Flash Encryption using a eFuses-based key.
|
||||
- 1
|
||||
* - ``DIS_DOWNLOAD_MANUAL_ENCRYPT``
|
||||
- If set, disable flash encryption when in download bootmodes.
|
||||
- 1
|
||||
* - ``{IDF_TARGET_CRYPT_CNT}``
|
||||
- Enable 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:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK and not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
.. list-table:: eFuses Used in Flash Encryption
|
||||
:widths: 25 40 10
|
||||
@@ -195,7 +251,35 @@ Assuming that the eFuse values are in their default states and the second stage
|
||||
|
||||
8. The device is then rebooted to start executing the encrypted image. The second stage bootloader calls the flash decryption block to decrypt the flash contents and then loads the decrypted contents into IRAM.
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 and SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
1. On the first power-on reset, all data in flash is un-encrypted (plaintext). The first stage (ROM) bootloader loads the second stage bootloader.
|
||||
|
||||
2. Second stage bootloader reads the ``{IDF_TARGET_CRYPT_CNT}`` eFuse value (``0b000``). Since the value is ``0`` (even number of bits set), it configures and enables the flash encryption block. For more information on the flash encryption block, see *{IDF_TARGET_NAME} Technical Reference Manual* > *eFuse Controller (eFuse)* > *Manual Encryption Block* [`PDF <{IDF_TARGET_TRM_EN_URL}#efuse>`__].
|
||||
|
||||
3. Second stage bootloader first checks if a valid key is already present in the eFuse (e.g., burned using espefuse tool) (if Flash Encryption is intended to be enabled using a eFuses-based key), or checks if there exists a valid key recovery info in the flash memory at the addresses: 0x0 and 0x1000 (if Flash Encryption is intended to be enabled using a Key Manager-based key), then the process of key generation is skipped and the same key is used for flash encryption process.
|
||||
|
||||
4. Otherwise, if using a efuses-based key second stage bootloader uses RNG (random) module to generate an 256 bit or 512 bit key, depending on the value of :ref:`Size of generated XTS-AES key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`, and then writes it into respectively one or two `BLOCK_KEYN` eFuses. The software also updates the ``KEY_PURPOSE_N`` for the blocks where the keys were stored. The key cannot be accessed via software as the write and read protection bits for one or two `BLOCK_KEYN` eFuses are set. ``KEY_PURPOSE_N`` field is write-protected as well. Whereas if using a Key Manager-based key, second stage bootloader writes the key recovery info to the flash memory at the address 0x0, followed by programming the ``KM_XTS_KEY_LENGTH_256`` and the ``FORCE_USE_KEY_MANAGER_KEY`` eFuses. The flash encryption operations happen entirely by hardware, and the key cannot be accessed via software.
|
||||
|
||||
5. Flash encryption block encrypts the flash contents - the second stage bootloader, applications and partitions marked as ``encrypted``. Encrypting in-place can take time, up to a minute for large partitions.
|
||||
|
||||
6. Second stage bootloader sets the first available bit in ``{IDF_TARGET_CRYPT_CNT}`` (0b001) to mark the flash contents as encrypted. Odd number of bits is set.
|
||||
|
||||
7. For :ref:`flash-enc-development-mode`, the second stage bootloader allows the UART bootloader to re-flash encrypted binaries. Also, the ``{IDF_TARGET_CRYPT_CNT}`` eFuse bits are NOT write-protected. In addition, the second stage bootloader by default sets the following eFuse bits:
|
||||
|
||||
.. list::
|
||||
|
||||
:esp32s2: - ``DIS_BOOT_REMAP``
|
||||
- ``DIS_DOWNLOAD_ICACHE``
|
||||
- ``DIS_DOWNLOAD_DCACHE``
|
||||
- ``HARD_DIS_JTAG``
|
||||
- ``DIS_LEGACY_SPI_BOOT``
|
||||
|
||||
8. For :ref:`flash-enc-release-mode`, the second stage bootloader sets all the eFuse bits set under development mode as well as ``DIS_DOWNLOAD_MANUAL_ENCRYPT``. It also write-protects the ``{IDF_TARGET_CRYPT_CNT}`` eFuse bits. To modify this behavior, see :ref:`uart-bootloader-encryption`.
|
||||
|
||||
9. The device is then rebooted to start executing the encrypted image. The second stage bootloader calls the flash decryption block to decrypt the flash contents and then loads the decrypted contents into IRAM.
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
1. On the first power-on reset, all data in flash is un-encrypted (plaintext). The first stage (ROM) bootloader loads the second stage bootloader.
|
||||
|
||||
@@ -221,23 +305,45 @@ Assuming that the eFuse values are in their default states and the second stage
|
||||
|
||||
8. The device is then rebooted to start executing the encrypted image. The second stage bootloader calls the flash decryption block to decrypt the flash contents and then loads the decrypted contents into IRAM.
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK and SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
1. On the first power-on reset, all data in flash is un-encrypted (plaintext). The first stage (ROM) bootloader loads the second stage bootloader.
|
||||
|
||||
2. Second stage bootloader reads the ``{IDF_TARGET_CRYPT_CNT}`` eFuse value (``0b000``). Since the value is ``0`` (even number of bits set), it configures and enables the flash encryption block. For more information on the flash encryption block, see `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_.
|
||||
|
||||
3. Second stage bootloader first checks if a valid key is already present in the eFuse (e.g., burned using espefuse tool) (if Flash Encryption is intended to be enabled using a eFuses-based key), or checks if there exists a valid key recovery info in the flash memory at the addresses: 0x0 and 0x1000 (if Flash Encryption is intended to be enabled using a Key Manager-based key), then the process of key generation is skipped and the same key is used for flash encryption process.
|
||||
|
||||
4. Otherwise, if using a efuses-based key second stage bootloader uses RNG (random) module to generate an 256 bit key, and then writes it into respectively one `BLOCK_KEYN` eFuses. The software also updates the ``KEY_PURPOSE_N`` for the block where the key were stored. The key cannot be accessed via software as the write and read protection bits for the one `BLOCK_KEYN` eFuses is set. ``KEY_PURPOSE_N`` field is write-protected as well. Whereas if using a Key Manager-based key, second stage bootloader writes the key recovery info to the flash memory at the address 0x0, followed by programming the ``KM_XTS_KEY_LENGTH_256`` and the ``FORCE_USE_KEY_MANAGER_KEY`` eFuses. The flash encryption operations happen entirely by hardware, and the key cannot be accessed via software.
|
||||
|
||||
5. Flash encryption block encrypts the flash contents - the second stage bootloader, applications and partitions marked as ``encrypted``. Encrypting in-place can take time, up to a minute for large partitions.
|
||||
|
||||
6. Second stage bootloader sets the first available bit in ``{IDF_TARGET_CRYPT_CNT}`` (0b001) to mark the flash contents as encrypted. Odd number of bits is set.
|
||||
|
||||
7. For :ref:`flash-enc-development-mode`, the second stage bootloader allows the UART bootloader to re-flash encrypted binaries. Also, the ``{IDF_TARGET_CRYPT_CNT}`` eFuse bits are NOT write-protected. In addition, the second stage bootloader by default sets the eFuse bits ``DIS_DOWNLOAD_ICACHE``, ``DIS_PAD_JTAG``, ``DIS_USB_JTAG`` and ``DIS_LEGACY_SPI_BOOT``.
|
||||
|
||||
8. For :ref:`flash-enc-release-mode`, the second stage bootloader sets all the eFuse bits set under development mode as well as ``DIS_DOWNLOAD_MANUAL_ENCRYPT``. It also write-protects the ``{IDF_TARGET_CRYPT_CNT}`` eFuse bits. To modify this behavior, see :ref:`uart-bootloader-encryption`.
|
||||
|
||||
9. The device is then rebooted to start executing the encrypted image. The second stage bootloader calls the flash decryption block to decrypt the flash contents and then loads the decrypted contents into IRAM.
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
|
||||
1. On the first power-on reset, all data in flash is un-encrypted (plaintext). The first stage (ROM) bootloader loads the second stage bootloader.
|
||||
|
||||
2. Second stage bootloader reads the ``{IDF_TARGET_CRYPT_CNT}`` eFuse value (``0b000``). Since the value is ``0`` (even number of bits set), it configures and enables the flash encryption block. For more information on the flash encryption block, see `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_.
|
||||
|
||||
3. Second stage bootloader uses RNG (random) module to generate an 256 bit key and then writes it into `BLOCK_KEYN` eFuse. The software also updates the ``KEY_PURPOSE_N`` for the block where the key is stored. The key cannot be accessed via software as the write and read protection bits for `BLOCK_KEYN` eFuse are set. ``KEY_PURPOSE_N`` field is write-protected as well. The flash encryption is completely conducted by hardware, and the key cannot be accessed via software. If a valid key is already present in the eFuse (e.g., burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process.
|
||||
3. Second stage bootloader first checks if a valid key is already present in the eFuse (e.g., burned using espefuse tool), then the process of key generation is skipped and the same key is used for flash encryption process.
|
||||
|
||||
4. Flash encryption block encrypts the flash contents - the second stage bootloader, applications and partitions marked as ``encrypted``. Encrypting in-place can take time, up to a minute for large partitions.
|
||||
4. Otherwise, second stage bootloader uses RNG (random) module to generate an 256 bit key and then writes it into `BLOCK_KEYN` eFuse. The software also updates the ``KEY_PURPOSE_N`` for the block where the key is stored. The key cannot be accessed via software as the write and read protection bits for `BLOCK_KEYN` eFuse are set. ``KEY_PURPOSE_N`` field is write-protected as well. The flash encryption is completely conducted by hardware, and the key cannot be accessed via software.
|
||||
|
||||
5. Second stage bootloader sets the first available bit in ``{IDF_TARGET_CRYPT_CNT}`` (0b001) to mark the flash contents as encrypted. Odd number of bits is set.
|
||||
5. Flash encryption block encrypts the flash contents - the second stage bootloader, applications and partitions marked as ``encrypted``. Encrypting in-place can take time, up to a minute for large partitions.
|
||||
|
||||
6. For :ref:`flash-enc-development-mode`, the second stage bootloader allows the UART bootloader to re-flash encrypted binaries. Also, the ``{IDF_TARGET_CRYPT_CNT}`` eFuse bits are NOT write-protected. In addition, the second stage bootloader by default sets the eFuse bits ``DIS_DOWNLOAD_ICACHE``, ``DIS_PAD_JTAG``, ``DIS_USB_JTAG`` and ``DIS_LEGACY_SPI_BOOT``.
|
||||
6. Second stage bootloader sets the first available bit in ``{IDF_TARGET_CRYPT_CNT}`` (0b001) to mark the flash contents as encrypted. Odd number of bits is set.
|
||||
|
||||
7. For :ref:`flash-enc-release-mode`, the second stage bootloader sets all the eFuse bits set under development mode as well as ``DIS_DOWNLOAD_MANUAL_ENCRYPT``. It also write-protects the ``{IDF_TARGET_CRYPT_CNT}`` eFuse bits. To modify this behavior, see :ref:`uart-bootloader-encryption`.
|
||||
7. For :ref:`flash-enc-development-mode`, the second stage bootloader allows the UART bootloader to re-flash encrypted binaries. Also, the ``{IDF_TARGET_CRYPT_CNT}`` eFuse bits are NOT write-protected. In addition, the second stage bootloader by default sets the eFuse bits ``DIS_DOWNLOAD_ICACHE``, ``DIS_PAD_JTAG``, ``DIS_USB_JTAG`` and ``DIS_LEGACY_SPI_BOOT``.
|
||||
|
||||
8. The device is then rebooted to start executing the encrypted image. The second stage bootloader calls the flash decryption block to decrypt the flash contents and then loads the decrypted contents into IRAM.
|
||||
8. For :ref:`flash-enc-release-mode`, the second stage bootloader sets all the eFuse bits set under development mode as well as ``DIS_DOWNLOAD_MANUAL_ENCRYPT``. It also write-protects the ``{IDF_TARGET_CRYPT_CNT}`` eFuse bits. To modify this behavior, see :ref:`uart-bootloader-encryption`.
|
||||
|
||||
9. The device is then rebooted to start executing the encrypted image. The second stage bootloader calls the flash decryption block to decrypt the flash contents and then loads the decrypted contents into IRAM.
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
|
||||
@@ -301,6 +407,7 @@ To test flash encryption process, take the following steps:
|
||||
:esp32: - :ref:`Select UART ROM download mode <CONFIG_SECURE_UART_ROM_DL_MODE>` (**enabled** by default). Note that for the ESP32 target, the choice is only available when :ref:`CONFIG_ESP32_REV_MIN` level is set to 3 (ESP32 V3).
|
||||
:not esp32: - :ref:`Select UART ROM download mode <CONFIG_SECURE_UART_ROM_DL_MODE>` (**enabled** by default).
|
||||
:SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS: - Set :ref:`Size of generated XTS-AES key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`.
|
||||
:SOC_KEY_MANAGER_SUPPORTED: - :ref:`Select the key source for the Flash Encryption Key <CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE>`.
|
||||
- :ref:`Select the appropriate bootloader log verbosity <CONFIG_BOOTLOADER_LOG_LEVEL>`.
|
||||
- Save the configuration and exit.
|
||||
|
||||
@@ -318,13 +425,27 @@ Enabling flash encryption will increase the size of bootloader, which might requ
|
||||
|
||||
This command will write to flash memory unencrypted images: the second stage bootloader, the partition table and applications. Once the flashing is complete, {IDF_TARGET_NAME} will reset. On the next boot, the second stage bootloader encrypts: the second stage 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.
|
||||
|
||||
A sample output of the first {IDF_TARGET_NAME} boot after enabling flash encryption is given below:
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
A sample output of the first {IDF_TARGET_NAME} boot after enabling flash encryption using a Key Manager-based key is given below:
|
||||
|
||||
.. include:: {IDF_TARGET_PATH_NAME}_log.inc
|
||||
:start-after: first_boot_enc_km
|
||||
:end-before: ------
|
||||
|
||||
A sample output of subsequent {IDF_TARGET_NAME} boot just mentions that flash encryption is already enabled (ESP-ROM log mentions that the Key Manager-based key is being used):
|
||||
|
||||
.. include:: {IDF_TARGET_PATH_NAME}_log.inc
|
||||
:start-after: already_en_enc_km
|
||||
:end-before: ------
|
||||
|
||||
A sample output of the first {IDF_TARGET_NAME} boot after enabling flash encryption using a eFuses-based key is given below:
|
||||
|
||||
.. include:: {IDF_TARGET_PATH_NAME}_log.inc
|
||||
:start-after: first_boot_enc
|
||||
:end-before: ------
|
||||
|
||||
A sample output of subsequent {IDF_TARGET_NAME} boots just mentions that flash encryption is already enabled:
|
||||
A sample output of subsequent {IDF_TARGET_NAME} boot just mentions that flash encryption is already enabled:
|
||||
|
||||
.. include:: {IDF_TARGET_PATH_NAME}_log.inc
|
||||
:start-after: already_en_enc
|
||||
@@ -338,7 +459,7 @@ At this stage, if you need to update and re-flash binaries, see :ref:`encrypt-pa
|
||||
Using Host Generated Key
|
||||
""""""""""""""""""""""""
|
||||
|
||||
It is possible to pre-generate a flash encryption key on the host computer and burn it into the eFuse. This allows you to pre-encrypt data on the host and flash already encrypted data without needing a plaintext flash update. This feature can be used in both :ref:`flash-enc-development-mode` and :ref:`flash-enc-release-mode`. Without a pre-generated key, data is flashed in plaintext and then {IDF_TARGET_NAME} encrypts the data in-place.
|
||||
It is possible to pre-generate a flash encryption key on the host computer and program it into the device. This allows you to pre-encrypt data on the host and flash already encrypted data without needing a plaintext flash update. This feature can be used in both :ref:`flash-enc-development-mode` and :ref:`flash-enc-release-mode`. Without a pre-generated key, data is flashed in plaintext and then {IDF_TARGET_NAME} encrypts the data in-place.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -350,7 +471,7 @@ It is possible to pre-generate a flash encryption key on the host computer and b
|
||||
|
||||
Note that {IDF_TARGET_NAME} only has one eFuse key block for both Secure Boot and Flash Encryption keys. Therefore, writing the host-generated Flash Encryption key must be done with Secure Boot key (if used), otherwise Secure Boot cannot be used.
|
||||
|
||||
To use a host generated key, take the following steps:
|
||||
To use a host generated key and program it into the eFuses of the device, take the following steps:
|
||||
|
||||
1. Ensure that you have an {IDF_TARGET_NAME} device with default flash encryption eFuse settings as shown in :ref:`flash-encryption-efuse`.
|
||||
|
||||
@@ -488,6 +609,78 @@ Enabling flash encryption will increase the size of bootloader, which might requ
|
||||
|
||||
This command will write to flash memory unencrypted images: the second stage bootloader, the partition table and applications. Once the flashing is complete, {IDF_TARGET_NAME} will reset. On the next boot, the second stage bootloader encrypts: the second stage 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.
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
To use a host generated key and deploy it into the device's Key Manager of the device, take the following steps:
|
||||
|
||||
1. Ensure that you have an {IDF_TARGET_NAME} device with default flash encryption eFuse settings as shown in :ref:`flash-encryption-efuse`.
|
||||
|
||||
See how to check :ref:`flash-encryption-status`.
|
||||
|
||||
2. Generate a random key by running:
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256
|
||||
|
||||
If :ref:`Size of generated XTS-AES key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>` is AES-128 (256-bit key):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py secure-generate-flash-encryption-key my_flash_encryption_key.bin
|
||||
|
||||
else if :ref:`Size of generated XTS-AES key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>` is AES-256 (512-bit key):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py secure-generate-flash-encryption-key --keylen 512 my_flash_encryption_key.bin
|
||||
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py secure-generate-flash-encryption-key my_flash_encryption_key.bin
|
||||
|
||||
|
||||
3. **Before the first encrypted boot**, deploy the key into your device's Key Manager using the AES-deploy mode of the Key Manager using a init key and an auxiliary key.
|
||||
|
||||
4. The deployment process will generate a key recovery information for the deployed key. Store this information at the flash address 0x0 using the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
esptool --port PORT --baud BAUD write-flash 0x0 key_recovery_info.bin
|
||||
|
||||
If the key is not deployed and the device is started after enabling Flash Encryption, the {IDF_TARGET_NAME} will generate and deploy a random key that software cannot access or modify.
|
||||
|
||||
.. note::
|
||||
|
||||
This command does not include any user files which should be written to the partitions on the flash memory. Please write them manually before running this command otherwise the files should be encrypted separately before writing.
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
This command will write to flash memory unencrypted images: the second stage bootloader, the partition table and applications. Once the flashing is complete, {IDF_TARGET_NAME} will reset. On the next boot, the second stage bootloader encrypts: the second stage 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.
|
||||
|
||||
|
||||
>>>>>>> 78b730138b6 (docs(key-manager): Add Key-Manager peripheral related documentation)
|
||||
5. In :ref:`project-configuration-menu`, do the following:
|
||||
|
||||
- :ref:`Enable flash encryption on boot <CONFIG_SECURE_FLASH_ENC_ENABLED>`
|
||||
- :ref:`Select encryption mode <CONFIG_SECURE_FLASH_ENCRYPTION_MODE>` (**Development mode** by default)
|
||||
- :ref:`Select flash encryption key source as the Key Manager<CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE>`
|
||||
- :ref:`Select the appropriate bootloader log verbosity <CONFIG_BOOTLOADER_LOG_LEVEL>`
|
||||
- Save the configuration and exit.
|
||||
|
||||
Enabling flash encryption will increase the size of bootloader, which might require updating partition table offset. See :ref:`bootloader-size`.
|
||||
|
||||
6. Run the command given below to build and flash the complete images.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py flash monitor
|
||||
|
||||
.. note::
|
||||
|
||||
This command does not include any user files which should be written to the partitions on the flash memory. Please write them manually before running this command otherwise the files should be encrypted separately before writing.
|
||||
|
||||
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`.
|
||||
@@ -828,7 +1021,9 @@ Key Points About Flash Encryption
|
||||
|
||||
:esp32: - The flash encryption algorithm is AES-256, where the key is "tweaked" with the offset address of each 32 byte block of flash. This means that every 32-byte block (two consecutive 16 byte AES blocks) is encrypted with a unique key derived from the flash encryption key.
|
||||
|
||||
:SOC_FLASH_ENCRYPTION_XTS_AES_256: - Flash memory contents is encrypted using XTS-AES-128 or XTS-AES-256. The flash encryption key is 256 bits and 512 bits respectively and stored in one or two ``BLOCK_KEYN`` eFuses internal to the chip and, by default, is protected from software access.
|
||||
:SOC_FLASH_ENCRYPTION_XTS_AES_256 and SOC_KEY_MANAGER_SUPPORTED: - Flash memory contents is encrypted using XTS-AES-128 or XTS-AES-256. The flash encryption key is 256 bits and 512 bits respectively and stored in one or two ``BLOCK_KEYN`` eFuses internal to the chip and, by default, is protected from software access.
|
||||
|
||||
:SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_KEY_MANAGER_SUPPORTED: - Flash memory contents is encrypted using XTS-AES-128 or XTS-AES-256. The flash encryption key is 256 bits and 512 bits respectively and stored in one or two ``BLOCK_KEYN`` eFuses internal to the chip if Flash Encryption is enabled using a eFuses-based key, whereas if Flash Encryption is enabled using a Key Manager-based key, the flash encryption key is stored in the Key Manager and, by default, is protected from software access.
|
||||
|
||||
:SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_FLASH_ENCRYPTION_XTS_AES_128_DERIVED: - Flash memory contents is encrypted using XTS-AES-128. The flash encryption key is 256 bits and stored in one ``BLOCK_KEYN`` eFuse internal to the chip and, by default, is protected from software access.
|
||||
|
||||
@@ -1003,7 +1198,13 @@ 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 is not necessary to keep a copy of the key or follow these steps, the simpler :ref:`encrypt-partitions` steps can be used.
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
Manually encrypting or decrypting files requires the flash encryption key to be deployed in the Key Manager or pre-burned in eFuses (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 is not necessary to keep a copy of the key or follow these steps, the simpler :ref:`encrypt-partitions` steps can be used.
|
||||
|
||||
.. only:: not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
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 is 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``).
|
||||
|
||||
|
||||
@@ -130,14 +130,57 @@ In this case all the eFuses related to Flash Encryption are written with help of
|
||||
|
||||
espsecure generate-flash-encryption-key --keylen 128 my_flash_encryption_key.bin
|
||||
|
||||
3. Burn the Flash Encryption key into eFuse
|
||||
3. Programming the generated Flash Encryption key into the device
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
a. If you intend to use the Key Manager to store the Flash Encryption key, generate the Key Recovery Information for the Flash Encryption key and store it in the flash memory at the address 0x0 using the command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
esptool --port PORT write-flash 0x0 key_recovery_info.bin
|
||||
|
||||
Once the Key Recovery info is stored in the flash memory, you also need to program the ``KM_XTS_KEY_LENGTH_256`` and the ``FORCE_USE_KEY_MANAGER_KEY`` eFuses.
|
||||
|
||||
.. warning::
|
||||
|
||||
This action **cannot be reverted**.
|
||||
|
||||
Bit 1 of the ``FORCE_USE_KEY_MANAGER_KEY`` eFuse is used to force using a Key Manager-based XTS-AES key. Once this eFuse is burned, eFuse-based Flash Encryption keys can no longer be used; the device will exclusively use the Key Manager for Flash Encryption key management.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
espefuse --port PORT burn-efuse FORCE_USE_KEY_MANAGER_KEY 2
|
||||
|
||||
The ``KM_XTS_KEY_LENGTH_256`` eFuse is used to control the length of the Key-Manager based XTS-AES key. Set this eFuse to 1 to use a 128-bit key, and to 0 to use a 256-bit key.
|
||||
|
||||
In case of using a 128-bit key, set the ``KM_XTS_KEY_LENGTH_256`` eFuse to 1.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
espefuse --port PORT burn-efuse KM_XTS_KEY_LENGTH_256 1
|
||||
|
||||
Otherwise in case of using a 256-bit key, set the ``KM_XTS_KEY_LENGTH_256`` eFuse to 0.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
espefuse --port PORT burn-efuse KM_XTS_KEY_LENGTH_256 0
|
||||
|
||||
<<<<<<< HEAD
|
||||
b. To store the Flash Encryption key in the eFuses, run the following commands:
|
||||
|
||||
.. only:: not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
To store the Flash Encryption key in the eFuses, run the following commands:
|
||||
=======
|
||||
|
||||
To store the Flash Encryption key in the eFuses, run the following commands:
|
||||
>>>>>>> 78b730138b6 (docs(key-manager): Add Key-Manager peripheral related documentation)
|
||||
|
||||
.. warning::
|
||||
|
||||
This action **cannot be reverted**.
|
||||
|
||||
It can be done by running:
|
||||
|
||||
.. only:: not SOC_FLASH_ENCRYPTION_XTS_AES
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -101,6 +101,24 @@ Flash Encryption Best Practices
|
||||
|
||||
Please refer to the :doc:`../api-reference/peripherals/ecdsa` and :doc:`../api-reference/peripherals/ds` guides for detailed documentation.
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
Key Manager
|
||||
~~~~~~~~~~~
|
||||
|
||||
The Key Manager peripheral in {IDF_TARGET_NAME} provides hardware-assisted **key deployment and recovery** for cryptographic keys. Keys are cryptographically bound to a Hardware Unique Key (HUK) that is unique to each chip, ensuring that key material is never exposed in software-accessible memory.
|
||||
|
||||
The Key Manager supports key management for the following cryptographic peripherals: :doc:`ECDSA <../api-reference/peripherals/ecdsa>`, :doc:`HMAC <../api-reference/peripherals/hmac>`, :doc:`Digital Signature (DS) <../api-reference/peripherals/ds>`, and Flash Encryption.
|
||||
|
||||
Please refer to :doc:`../api-reference/peripherals/key_manager` for detailed documentation.
|
||||
|
||||
Key Manager Best Practices
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* Protect the ``key_recovery_info`` of a Key Manager-deployed key against unauthorized modification or loss.
|
||||
* Lock Key Manager's security-related eFuses after successful key deployment to prevent re-deployment of a key of the same type.
|
||||
* Avoid deploying new XTS-AES keys when Flash Encryption is already enabled unless explicitly intended.
|
||||
|
||||
.. only:: SOC_MEMPROT_SUPPORTED or SOC_CPU_IDRAM_SPLIT_USING_PMP
|
||||
|
||||
Memory Protection
|
||||
|
||||
@@ -3,7 +3,13 @@
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
数字签名 (DS) 模块利用 RSA 硬件加速器为信息签名。HMAC 作为密钥派生函数,使用 eFuse 作为输入密钥,输出一组加密参数。随后,数字签名模块利用这组预加密的参数,计算出签名。以上过程均在硬件中完成,因此在计算签名时,软件无法获取 RSA 参数的解密密钥,也无法获取 HMAC 密钥派生函数的输入密钥。
|
||||
数字签名 (DS) 模块利用 RSA 硬件加速器为信息签名。HMAC 作为密钥派生函数,使用 eFuse 作为输入密钥,输出一组加密参数。随后,数字签名模块利用这组预加密的参数,计算出签名。
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
在 {IDF_TARGET_NAME} 上,数字签名 (DS) 模块也可以使用存储在密钥管理器中的密钥,而非 eFuse 密钥块。AES 加密密钥可以通过密钥管理器直接部署,类型为 :cpp:enumerator:`ESP_KEY_MGR_DS_KEY`。详情请参阅 :ref:`key-manager`。
|
||||
|
||||
以上过程均在硬件中完成,因此在计算签名时,软件无法获取 RSA 参数的解密密钥,也无法获取 HMAC 密钥派生函数的输入密钥。
|
||||
|
||||
签名计算所涉及的硬件信息以及所用寄存器的有关信息,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。
|
||||
|
||||
@@ -112,7 +118,11 @@ TLS 连接所需的 DS 外设配置
|
||||
|
||||
此前位于 ``examples/protocols/mqtt/ssl_ds`` 目录下的 SSL 双向认证示例现已随独立的 `espressif/mqtt <https://components.espressif.com/components/espressif/mqtt>`__ 组件一同提供。请参照该组件文档获取 SSL DS 示例,并与 ESP-MQTT 一同构建。该示例仍使用 ``mqtt_client`` (由 ESP-MQTT 实现),通过双向认证 TLS 连接至 ``test.mosquitto.org``,其中 TLS 通信层仍由 ESP-TLS 实现。
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
如果 :cpp:member:`esp_ds_data_ctx_t::efuse_key_id` 和 :cpp:member:`esp_rsa_ds_opaque_key_t::key_recovery_info` 均已设置,ESP-DS PSA 驱动程序将优先使用基于密钥管理器的 DS 密钥,而非基于 eFuse 的 DS 密钥。
|
||||
|
||||
API 参考
|
||||
--------
|
||||
|
||||
.. include-build-file:: inc/esp_ds.inc
|
||||
.. include-build-file:: inc/psa_crypto_driver_esp_rsa_ds_contexts.inc
|
||||
|
||||
@@ -24,7 +24,13 @@ ECDSA 外设可以为 TLS 双向身份验证等用例建立 **安全设备身份
|
||||
{IDF_TARGET_NAME} 上的 ECDSA
|
||||
----------------------------
|
||||
|
||||
在 {IDF_TARGET_NAME} 上,ECDSA 模块使用烧录到 eFuse 块中的密钥。密码模块外的任何资源都不可访问此密钥(默认模式),从而避免密钥泄露。
|
||||
在 {IDF_TARGET_NAME} 上,ECDSA 模块使用烧录到 eFuse 块中的密钥。
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
在 {IDF_TARGET_NAME} 上,ECDSA 模块也支持将密钥存储在密钥管理器中,详情请参阅 :ref:`key-manager`。
|
||||
|
||||
密码模块外的任何资源都不可访问此密钥(默认模式),从而避免密钥泄露。
|
||||
|
||||
ECDSA 密钥存储
|
||||
^^^^^^^^^^^^^^
|
||||
@@ -53,6 +59,8 @@ ECDSA 密钥存储
|
||||
|
||||
ECDSA 密钥可以通过 ``idf.py`` 脚本在外部编程。以下是关于编程 ECDSA 密钥的示例:
|
||||
|
||||
使用 eFuse 存储 ECDSA 密钥:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
idf.py efuse-burn-key <BLOCK_NUM> </path/to/ecdsa_private_key.pem> ECDSA_KEY
|
||||
@@ -70,8 +78,18 @@ ECDSA 密钥可以通过 ``idf.py`` 脚本在外部编程。以下是关于编
|
||||
六个物理 eFuse 块可作为 ECDSA 模块的密钥:块 4 ~ 块 9。例如,对于块 4(第一个密钥块),参数为 ``BLOCK_KEY0``。
|
||||
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
使用密钥管理器存储 ECDSA 密钥:
|
||||
|
||||
ECDSA 私钥可以存储在密钥管理器中,详情请参阅 :ref:`key-manager`。
|
||||
|
||||
将 ECDSA 密钥部署到密钥管理器中,对于持久化密钥,需将生成的密钥恢复信息存储在 flash 中。
|
||||
|
||||
另外,ECDSA 密钥也可以通过在目标上运行的应用程序进行编程。
|
||||
|
||||
使用 eFuse 存储 ECDSA 密钥:
|
||||
|
||||
以下代码片段使用 :cpp:func:`esp_efuse_write_key` 将 eFuse 中的物理密钥块 0 的密钥目的设置为 :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -26,7 +26,13 @@
|
||||
{IDF_TARGET_NAME} 上的 HMAC
|
||||
-----------------------------
|
||||
|
||||
在 {IDF_TARGET_NAME} HMAC 模块的 eFuse 中会烧录一个密钥,可将该 eFuse 密钥设置为禁止所有外部资源访问,避免密钥泄露。
|
||||
在 {IDF_TARGET_NAME} HMAC 模块的 eFuse 中会烧录一个密钥。
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
在 {IDF_TARGET_NAME} 上,HMAC 模块也支持将密钥存储在密钥管理器中,详情请参阅 :ref:`key-manager`。
|
||||
|
||||
可将该密钥设置为禁止所有外部资源访问,避免密钥泄露。
|
||||
|
||||
此外,在 {IDF_TARGET_NAME} 上的 HMAC 有以下三种应用场景:
|
||||
|
||||
@@ -142,6 +148,8 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接
|
||||
|
||||
以下为针对特定应用场景的实例代码,可用于设置 eFuse 密钥,并将其用于计算支持软件使用的 HMAC。
|
||||
|
||||
使用 eFuse 存储 HMAC 密钥:
|
||||
|
||||
``esp_efuse_write_key`` 可以设置 eFuse 中的物理密钥块 4,并设置其功能。``ESP_EFUSE_KEY_PURPOSE_HMAC_UP`` (8) 表明,该密钥仅适用于生成支持软件使用的 HMAC。
|
||||
|
||||
.. code-block:: c
|
||||
@@ -162,6 +170,8 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接
|
||||
|
||||
接下来可以通过 PSA Crypto API,使用已存储的密钥来计算供软件使用的 HMAC。
|
||||
|
||||
使用基于 eFuse 的 HMAC 密钥:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include "psa/crypto.h"
|
||||
@@ -181,9 +191,8 @@ HMAC 的第三种应用场景是将其作为密钥,启用软禁用的 JTAG 接
|
||||
psa_set_key_bits(&attributes, 256);
|
||||
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_ESP_HMAC_VOLATILE);
|
||||
|
||||
// 创建不透明密钥引用
|
||||
// 为基于 eFuse 的密钥创建不透明密钥引用
|
||||
esp_hmac_opaque_key_t opaque_key = {
|
||||
.use_km_key = false,
|
||||
.efuse_key_id = HMAC_KEY4,
|
||||
};
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
:SOC_I2S_SUPPORTED: i2s
|
||||
:SOC_I3C_MASTER_SUPPORTED: i3c_master
|
||||
:SOC_ISP_SUPPORTED: isp
|
||||
:SOC_KEY_MANAGER_SUPPORTED: key_manager
|
||||
lcd/index
|
||||
:SOC_GP_LDO_SUPPORTED: ldo_regulator
|
||||
ledc
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
.. _key-manager:
|
||||
|
||||
密钥管理器
|
||||
==========
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
{IDF_TARGET_NAME} 的密钥管理器外设为密码密钥提供了硬件辅助的 **密钥部署和密钥恢复** 功能。它允许对密码密钥进行配置和使用,而无需将明文密钥材料存储在 flash、RAM 或 eFuse 中。密钥管理器适用于需要安全处理长期密码密钥的应用程序。
|
||||
|
||||
.. only:: esp32p4
|
||||
|
||||
.. note::
|
||||
|
||||
密钥管理器外设仅支持 ESP32-P4 芯片版本 v3.x (rev >= 3)。
|
||||
|
||||
.. only:: esp32c5
|
||||
|
||||
.. note::
|
||||
|
||||
密钥管理器外设仅支持 ESP32-C5 芯片版本 >= v1.2。
|
||||
|
||||
密钥管理器具有以下特性:
|
||||
|
||||
- **设备唯一性**
|
||||
|
||||
密钥通过加密手段绑定到硬件唯一密钥 (HUK),而 HUK 对每个芯片都是唯一的。
|
||||
|
||||
- **无明文密钥存储**
|
||||
|
||||
密钥材料不会暴露于软件可访问的内存中。
|
||||
|
||||
- **灵活的密钥生命周期**
|
||||
|
||||
密钥可以被部署、恢复或替换为新密钥,无需为每个密钥重新烧录 eFuse。
|
||||
|
||||
- **抗物理提取**
|
||||
|
||||
读取 flash 或 eFuse 的内容不会泄露可用的密钥材料。
|
||||
|
||||
硬件唯一密钥 (HUK)
|
||||
-------------------
|
||||
|
||||
硬件唯一密钥 (HUK) 是完全由硬件 HUK 外设生成的设备专属唯一密钥。它通过 SRAM 物理不可克隆函数 (PUF) 生成,并使用存储在密钥管理器已部署密钥的密钥恢复信息中的 HUK 恢复信息进行重建。有关 HUK 外设的更多详情,请参阅 *{IDF_TARGET_NAME} 技术参考手册* > *密钥管理器章节* [`PDF <{IDF_TARGET_TRM_EN_URL}>`__] > *HUK Generator*。
|
||||
|
||||
HUK 是所有通过密钥管理器部署的密钥的信任根。
|
||||
|
||||
密钥部署与密钥恢复
|
||||
------------------
|
||||
|
||||
密钥管理器在两个不同阶段中工作:
|
||||
|
||||
- **密钥部署**
|
||||
|
||||
密码密钥在芯片内部生成或被安全导入,并与 HUK 绑定。此步骤通常在生产阶段、首次启动时,或在应用程序运行时生成瞬态或持久密钥时执行。
|
||||
|
||||
- **密钥恢复**
|
||||
|
||||
在后续启动过程中,密钥管理器部署的持久密钥使用之前生成的密钥恢复信息进行还原,而不会暴露密钥值。
|
||||
|
||||
在部署过程中,密钥管理器生成一个称为 :cpp:type:`esp_key_mgr_key_recovery_info_t` 的数据结构。对于持久密钥,应用程序必须将此数据存储在非易失性存储器(例如 flash)中,以便在后续启动时恢复密钥。
|
||||
|
||||
支持的密钥类型
|
||||
--------------
|
||||
|
||||
密钥管理器可以管理以下密钥类型:
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_KEY_MANAGER_ECDSA_KEY_DEPLOY: - ECDSA
|
||||
:SOC_KEY_MANAGER_FE_KEY_DEPLOY: - Flash 加密 (XTS-AES)
|
||||
:SOC_KEY_MANAGER_HMAC_KEY_DEPLOY: - HMAC
|
||||
:SOC_KEY_MANAGER_DS_KEY_DEPLOY: - 数字签名外设
|
||||
:SOC_KEY_MANAGER_FE_KEY_DEPLOY: - PSRAM 加密
|
||||
|
||||
每个密钥都与一个 :cpp:type:`esp_key_mgr_key_purpose_t` 相关联,它定义了密钥如何被硬件外设使用。
|
||||
|
||||
密钥部署模式
|
||||
------------
|
||||
|
||||
密钥管理器提供多种密钥部署模式,以满足不同的配置和安全需求。
|
||||
|
||||
随机部署模式
|
||||
^^^^^^^^^^^^
|
||||
|
||||
在此模式下,密钥管理器在内部生成一个随机私钥。
|
||||
|
||||
- 应用程序软件不知道密钥值
|
||||
- 不需要外部密钥材料
|
||||
- 适用于不需要备份或导出密钥的场景
|
||||
|
||||
AES 部署模式
|
||||
^^^^^^^^^^^^
|
||||
|
||||
在此模式下,用户指定的私钥被安全部署。
|
||||
|
||||
- 密钥在传输到芯片之前进行加密
|
||||
- 使用辅助密钥材料保护部署过程
|
||||
- 适用于需要预定义密钥值的工厂配置场景
|
||||
|
||||
ECDH0 部署模式
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
在此模式下,私钥通过椭圆曲线 Diffie-Hellman (ECDH) 协商生成。
|
||||
|
||||
- 最终私钥不会被传输
|
||||
- 部署过程可以通过不受信任的信道进行
|
||||
- 适用于高安全性的配置环境
|
||||
|
||||
有关各种部署模式的详细信息,请参阅 *{IDF_TARGET_NAME} 技术参考手册* > *密钥管理器章节* [`PDF <{IDF_TARGET_TRM_EN_URL}>`__] > *Key Manager*。
|
||||
|
||||
.. ECDH1 Deploy Mode
|
||||
.. ~~~~~~~~~~~~~~~~~
|
||||
..
|
||||
.. This mode is similar to ECDH0 Deploy Mode, with additional flexibility for manufacturing workflows.
|
||||
..
|
||||
.. - Supports negotiated key deployment using auxiliary recovery data
|
||||
.. - Allows updating deployed keys by replacing auxiliary information
|
||||
.. - Intended for large-scale manufacturing with controlled trust assumptions
|
||||
|
||||
典型工作流程
|
||||
------------
|
||||
|
||||
首次启动或生产配置
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
典型的配置流程包括:
|
||||
|
||||
1. 生成硬件唯一密钥 (HUK)
|
||||
2. 使用适当的部署模式部署所需的密码密钥
|
||||
3. 将生成的 ``key_recovery_info`` 存储到非易失性存储器中
|
||||
4. 如有需要,锁定相关安全配置 eFuse
|
||||
|
||||
此过程通常每台设备仅执行一次。
|
||||
|
||||
正常启动
|
||||
^^^^^^^^
|
||||
|
||||
在正常启动过程中:
|
||||
|
||||
1. 应用程序提供之前生成并存储的密钥管理器已部署密钥的 ``key_recovery_info``
|
||||
2. HUK 由硬件自动重建
|
||||
3. 密钥管理器在内部恢复已部署的密钥
|
||||
4. 密码外设可以使用恢复的密钥
|
||||
|
||||
安全注意事项
|
||||
------------
|
||||
|
||||
使用密钥管理器的应用程序应注意以下事项:
|
||||
|
||||
- 保护密钥管理器已部署密钥的 ``key_recovery_info``,防止未经授权的修改或丢失
|
||||
- 密钥部署成功后,锁定密钥管理器的安全相关 eFuse,以防止同类型密钥被重新部署
|
||||
- 除非有明确意图,否则在 Flash 加密已启用时,应避免部署新的 XTS-AES 密钥
|
||||
|
||||
API 参考
|
||||
--------
|
||||
|
||||
.. include-build-file:: inc/esp_key_mgr.inc
|
||||
.. include-build-file:: inc/key_mgr_types.inc
|
||||
|
||||
应用示例
|
||||
--------
|
||||
|
||||
以下示例演示了如何使用密钥管理器进行密钥部署,以及如何使用已部署的密钥执行签名操作:
|
||||
|
||||
请参阅 :example:`security/key_manager` 查看该示例。
|
||||
|
||||
该示例展示了如何:
|
||||
|
||||
- 初始化密钥管理器
|
||||
- 使用 AES 部署模式部署密钥
|
||||
- 使用 PSA 接口通过密钥管理器已部署的密钥执行签名操作
|
||||
@@ -66,68 +66,72 @@
|
||||
|
||||
------
|
||||
|
||||
.. first_boot_enc_km
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ESP-ROM:esp32c5-eco3-20250704
|
||||
Build:Jul 4 2025
|
||||
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
|
||||
SPI mode:DIO, clock div:1
|
||||
load:0x40855820,len:0x3a60
|
||||
load:0x4084bba0,len:0xdf4
|
||||
load:0x4084e5a0,len:0x566c
|
||||
entry 0x4084bbaa
|
||||
I (23) boot: ESP-IDF v6.0-dev-3140-ge16a2fb13ad-dirt 2nd stage bootloader
|
||||
I (24) boot: compile time Oct 27 2025 15:35:09
|
||||
I (67) boot: chip revision: v1.1
|
||||
I (70) boot: efuse block revision: v0.3
|
||||
I (88) boot.esp32c5: SPI Speed : 80MHz
|
||||
I (92) boot.esp32c5: SPI Mode : DIO
|
||||
I (96) boot.esp32c5: SPI Flash Size : 2MB
|
||||
I (103) boot: Enabling RNG early entropy source...
|
||||
I (138) boot: Partition Table:
|
||||
I (141) boot: ## Label Usage Type ST Offset Length
|
||||
I (154) boot: 0 nvs WiFi data 01 02 0000e000 00006000
|
||||
I (168) boot: 1 phy_init RF data 01 01 00014000 00001000
|
||||
I (182) boot: 2 factory factory app 00 00 00020000 00100000
|
||||
I (189) boot: End of partition table
|
||||
I (283) esp_image: segment 0: paddr=00020020 vaddr=42070020 size=32f1ch (208668) map
|
||||
I (377) esp_image: segment 1: paddr=00052f44 vaddr=40800000 size=0a2a4h ( 41636) load
|
||||
I (445) esp_image: segment 2: paddr=0005d1f0 vaddr=4080a300 size=02ccch ( 11468) load
|
||||
I (512) esp_image: segment 3: paddr=0005fec4 vaddr=00000000 size=00154h ( 340)
|
||||
I (580) esp_image: segment 4: paddr=00060020 vaddr=42000020 size=63804h (407556) map
|
||||
I (761) boot: Loaded app from partition at offset 0x20000
|
||||
I (764) boot: Checking flash encryption...
|
||||
I (788) efuse: Batch mode of writing fields is enabled
|
||||
I (807) flash_encrypt: Deploying new flash encryption key using Key Manager
|
||||
W (898) flash_encrypt: Not disabling UART bootloader encryption
|
||||
I (904) flash_encrypt: Disable UART bootloader cache...
|
||||
W (917) flash_encrypt: Not disabling JTAG - SECURITY COMPROMISED
|
||||
I (930) efuse: BURN BLOCK0
|
||||
I (935) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (938) efuse: Batch mode. Prepared fields are committed
|
||||
I (1028) esp_image: segment 0: paddr=00002020 vaddr=40855820 size=03a60h ( 14944)
|
||||
I (1096) esp_image: segment 1: paddr=00005a88 vaddr=4084bba0 size=00df4h ( 3572)
|
||||
I (1165) esp_image: segment 2: paddr=00006884 vaddr=4084e5a0 size=0566ch ( 22124)
|
||||
I (1508) flash_encrypt: bootloader encrypted successfully
|
||||
I (1535) flash_encrypt: partition table encrypted and loaded successfully
|
||||
I (1616) esp_image: segment 0: paddr=00020020 vaddr=42070020 size=32f1ch (208668) map
|
||||
I (1711) esp_image: segment 1: paddr=00052f44 vaddr=40800000 size=0a2a4h ( 41636)
|
||||
I (1779) esp_image: segment 2: paddr=0005d1f0 vaddr=4080a300 size=02ccch ( 11468)
|
||||
I (1847) esp_image: segment 3: paddr=0005fec4 vaddr=00000000 size=00154h ( 340)
|
||||
I (1916) esp_image: segment 4: paddr=00060020 vaddr=42000020 size=63804h (407556) map
|
||||
I (2096) flash_encrypt: Encrypting partition 2 at offset 0x20000 (length 0xa3850)...
|
||||
I (5652) flash_encrypt: Done encrypting
|
||||
I (5667) efuse: BURN BLOCK0
|
||||
I (5671) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (5675) flash_encrypt: Flash encryption completed
|
||||
I (5679) boot: Resetting with flash encryption enabled...
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
.. already_en_enc
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
rst:0x1 (POWERON),boot:0x3d (SPI_FAST_FLASH_BOOT)
|
||||
SPI mode:DIO, clock div:2
|
||||
load:0x40855c10,len:0x2be8
|
||||
load:0x4084c7a0,len:0x6f8
|
||||
load:0x4084e9a0,len:0x418c
|
||||
entry 0x4084c804
|
||||
I (32) boot: ESP-IDF v5.3-dev-3860-g5d36288649 2nd stage bootloader
|
||||
I (33) boot: compile time May 7 2024 17:24:43
|
||||
I (34) boot: chip revision: v0.0
|
||||
I (37) boot.esp32c5: SPI Speed : 40MHz
|
||||
I (42) boot.esp32c5: SPI Mode : DIO
|
||||
I (46) boot.esp32c5: SPI Flash Size : 2MB
|
||||
I (51) boot: Enabling RNG early entropy source...
|
||||
I (64) boot: Partition Table:
|
||||
I (67) boot: ## Label Usage Type ST Offset Length
|
||||
I (74) boot: 0 nvs WiFi data 01 02 0000e000 00006000
|
||||
I (82) boot: 1 storage Unknown data 01 ff 00014000 00001000
|
||||
I (89) boot: 2 factory factory app 00 00 00020000 00100000
|
||||
I (97) boot: 3 nvs_key NVS keys 01 04 00120000 00001000
|
||||
I (104) boot: 4 custom_nvs WiFi data 01 02 00121000 00006000
|
||||
I (113) boot: End of partition table
|
||||
I (116) esp_image: segment 0: paddr=00020020 vaddr=42010020 size=095c4h ( 38340) map
|
||||
I (169) esp_image: segment 1: paddr=000295ec vaddr=40800000 size=06a2ch ( 27180) load
|
||||
I (197) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=0f4d4h ( 62676) map
|
||||
I (256) esp_image: segment 3: paddr=0003f4fc vaddr=40806a2c size=00b78h ( 2936) load
|
||||
I (261) esp_image: segment 4: paddr=0004007c vaddr=408075b0 size=00d18h ( 3352) load
|
||||
I (269) boot: Loaded app from partition at offset 0x20000
|
||||
I (270) boot: Checking flash encryption...
|
||||
I (273) efuse: Batch mode of writing fields is enabled
|
||||
I (278) flash_encrypt: Generating new flash encryption key...
|
||||
I (295) efuse: Writing EFUSE_BLK_KEY0 with purpose 4
|
||||
W (300) flash_encrypt: Not disabling UART bootloader encryption
|
||||
I (305) flash_encrypt: Disable JTAG...
|
||||
I (312) efuse: BURN BLOCK4
|
||||
I (317) efuse: BURN BLOCK4 - OK (write block == read block)
|
||||
I (319) efuse: BURN BLOCK0
|
||||
I (325) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (330) efuse: Batch mode. Prepared fields are committed
|
||||
I (335) esp_image: segment 0: paddr=00002020 vaddr=40855c10 size=02be8h ( 11240)
|
||||
I (353) esp_image: segment 1: paddr=00004c10 vaddr=4084c7a0 size=006f8h ( 1784)
|
||||
I (356) esp_image: segment 2: paddr=00005310 vaddr=4084e9a0 size=0418ch ( 16780)
|
||||
I (1131) flash_encrypt: bootloader encrypted successfully
|
||||
I (1229) flash_encrypt: partition table encrypted and loaded successfully
|
||||
I (1230) flash_encrypt: Encrypting partition 1 at offset 0x14000 (length 0x1000)...
|
||||
I (1325) flash_encrypt: Done encrypting
|
||||
I (1325) esp_image: segment 0: paddr=00020020 vaddr=42010020 size=095c4h ( 38340) map
|
||||
I (1362) esp_image: segment 1: paddr=000295ec vaddr=40800000 size=06a2ch ( 27180)
|
||||
I (1389) esp_image: segment 2: paddr=00030020 vaddr=42000020 size=0f4d4h ( 62676) map
|
||||
I (1448) esp_image: segment 3: paddr=0003f4fc vaddr=40806a2c size=00b78h ( 2936)
|
||||
I (1453) esp_image: segment 4: paddr=0004007c vaddr=408075b0 size=00d18h ( 3352)
|
||||
I (1458) flash_encrypt: Encrypting partition 2 at offset 0x20000 (length 0x100000)...
|
||||
I (24332) flash_encrypt: Done encrypting
|
||||
I (24332) flash_encrypt: Encrypting partition 3 at offset 0x120000 (length 0x1000)...
|
||||
I (24422) flash_encrypt: Done encrypting
|
||||
I (24423) efuse: BURN BLOCK0
|
||||
I (24425) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (24427) flash_encrypt: Flash encryption completed
|
||||
I (24431) boot: Resetting with flash encryption enabled...
|
||||
ESP-ROM:esp32c5-20240329
|
||||
Build:Mar 29 2024
|
||||
rst:0x3 (RTC_SW_HPSYS),boot:0x3d (SPI_FAST_FLASH_BOOT)
|
||||
@@ -193,3 +197,79 @@
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
.. already_en_enc_km
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ESP-ROM:esp32c5-eco3-20250704
|
||||
Build:Jul 4 2025
|
||||
rst:0x1 (POWERON),boot:0x18 (SPI_FAST_FLASH_BOOT)
|
||||
use sector0 for km info
|
||||
use KM derived key
|
||||
SPI mode:DIO, clock div:1
|
||||
load:0x40855820,len:0x3a94
|
||||
load:0x4084bba0,len:0xd84
|
||||
load:0x4084e5a0,len:0x5670
|
||||
entry 0x4084bbaa
|
||||
I (27) boot: ESP-IDF v6.0-dev-3139-gb813f413096-dirt 2nd stage bootloader
|
||||
I (28) boot: compile time Oct 27 2025 18:14:49
|
||||
W (39) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (53) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (67) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (80) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (94) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
W (108) MMU: mmu_ll_write_entry mmu_id=0, entry_id=511, mmu_val=0x00000000, target=1
|
||||
I (116) boot: chip revision: v1.1
|
||||
I (119) boot: efuse block revision: v0.3
|
||||
I (137) boot.esp32c5: SPI Speed : 80MHz
|
||||
I (141) boot.esp32c5: SPI Mode : DIO
|
||||
I (145) boot.esp32c5: SPI Flash Size : 2MB
|
||||
I (149) boot: Enabling RNG early entropy source...
|
||||
W (163) MMU: mmu_ll_write_entry mmu_id=0, entry_id=0, mmu_val=0x00000000, target=1
|
||||
I (191) boot: Partition Table:
|
||||
I (194) boot: ## Label Usage Type ST Offset Length
|
||||
I (208) boot: 0 nvs WiFi data 01 02 0000e000 00006000
|
||||
I (222) boot: 1 phy_init RF data 01 01 00014000 00001000
|
||||
I (235) boot: 2 factory factory app 00 00 00020000 00100000
|
||||
I (242) boot: End of partition table
|
||||
I (396) esp_image: segment 0: paddr=00020020 vaddr=42070020 size=32f1ch (208668) map
|
||||
I (539) esp_image: segment 1: paddr=00052f44 vaddr=40800000 size=0a2a4h ( 41636) load
|
||||
I (629) esp_image: segment 2: paddr=0005d1f0 vaddr=4080a300 size=02ccch ( 11468) load
|
||||
I (719) esp_image: segment 3: paddr=0005fec4 vaddr=00000000 size=00154h ( 340)
|
||||
I (816) esp_image: segment 4: paddr=00060020 vaddr=42000020 size=6378ch (407436) map
|
||||
I (1114) boot: Loaded app from partition at offset 0x20000
|
||||
I (1116) boot: Checking flash encryption...
|
||||
I (1133) flash_encrypt: flash encryption is enabled (1 plaintext flashes left)
|
||||
I (1140) boot: Disabling RNG early entropy source...
|
||||
I (1301) MSPI Timing: Enter flash timing tuning
|
||||
I (1434) cpu_start: Unicore app
|
||||
I (1468) cpu_start: GPIO 12 and 11 are used as console UART I/O pins
|
||||
I (1479) cpu_start: Pro cpu start user code
|
||||
I (1483) cpu_start: cpu freq: 240000000 Hz
|
||||
I (1493) app_init: Application information:
|
||||
I (1496) app_init: Project name: mbedtls_test
|
||||
I (1501) app_init: App version: qa-test-esp32c61-master-2025070
|
||||
I (1507) app_init: Compile time: Oct 27 2025 15:56:18
|
||||
I (1512) app_init: ELF file SHA256: c5f7f520c...
|
||||
I (1517) app_init: ESP-IDF: v6.0-dev-3140-ge16a2fb13ad-dirt
|
||||
I (1528) efuse_init: Min chip rev: v1.0
|
||||
I (1532) efuse_init: Max chip rev: v1.99
|
||||
I (1536) efuse_init: Chip rev: v1.1
|
||||
I (1669) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (1680) heap_init: At 4080FCB0 len 0004C8F0 (306 KiB): RAM
|
||||
I (1685) heap_init: At 4085C5A0 len 00002F58 (11 KiB): RAM
|
||||
I (1695) heap_init: At 50000000 len 00003FE8 (15 KiB): RTCRAM
|
||||
I (1800) spi_flash: detected chip: generic
|
||||
I (1804) spi_flash: flash io: dio
|
||||
W (1807) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
W (1833) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)
|
||||
I (1867) sleep_gpio: Configure to isolate all GPIO pins in sleep state
|
||||
I (1873) sleep_gpio: Enable automatic switching of GPIO sleep configuration
|
||||
I (1926) main_task: Started on CPU0
|
||||
I (1926) main_task: Calling app_main()
|
||||
I (1936) main_task: Returned from app_main()
|
||||
|
||||
|
||||
------
|
||||
|
||||
@@ -70,6 +70,72 @@
|
||||
|
||||
------
|
||||
|
||||
.. first_boot_enc_km
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ESP-ROM:esp32p4-eco5-20250430
|
||||
Build:Apr 30 2025
|
||||
rst:0x17 (CHIP_USB_UART_RESET),boot:0xc (SPI_FAST_FLASH_BOOT)
|
||||
Core0 Saved PC:0x4fc0130e
|
||||
Core1 Saved PC:0x4fc05fa4
|
||||
SPI mode:DIO, clock div:1
|
||||
load:0x4ffb6240,len:0x3870
|
||||
load:0x4ffac2c0,len:0x179c
|
||||
load:0x4ffaefc0,len:0x4ed8
|
||||
entry 0x4ffac2ca
|
||||
I (38) boot: ESP-IDF v6.0-dev-2918-g6629f96afca-dirt 2nd stage bootloader
|
||||
I (38) boot: compile time Oct 14 2025 08:50:07
|
||||
I (39) boot: Multicore bootloader
|
||||
I (85) boot: chip revision: v3.0
|
||||
I (88) boot: efuse block revision: v1.0
|
||||
I (106) boot.esp32p4: SPI Speed : 80MHz
|
||||
I (110) boot.esp32p4: SPI Mode : DIO
|
||||
I (114) boot.esp32p4: SPI Flash Size : 2MB
|
||||
I (121) boot: Enabling RNG early entropy source...
|
||||
I (156) boot: Partition Table:
|
||||
I (159) boot: ## Label Usage Type ST Offset Length
|
||||
I (173) boot: 0 factory factory app 00 00 00010000 00150000
|
||||
I (187) boot: 1 storage Unknown data 01 81 00160000 00050000
|
||||
I (194) boot: End of partition table
|
||||
I (287) esp_image: segment 0: paddr=00010020 vaddr=40030020 size=0d1e8h ( 53736) map
|
||||
I (355) esp_image: segment 1: paddr=0001d210 vaddr=30100000 size=00044h ( 68) load
|
||||
I (423) esp_image: segment 2: paddr=0001d25c vaddr=4ff20000 size=02dbch ( 11708) load
|
||||
I (491) esp_image: segment 3: paddr=00020020 vaddr=40000020 size=21834h (137268) map
|
||||
I (567) esp_image: segment 4: paddr=0004185c vaddr=4ff22dbc size=094e8h ( 38120) load
|
||||
I (635) esp_image: segment 5: paddr=0004ad4c vaddr=4ff2c300 size=044ech ( 17644) load
|
||||
I (750) boot: Loaded app from partition at offset 0x10000
|
||||
I (752) boot: Checking flash encryption...
|
||||
I (777) efuse: Batch mode of writing fields is enabled
|
||||
I (796) flash_encrypt: Deploying new flash encryption key using Key Manager
|
||||
W (933) flash_encrypt: Not disabling UART bootloader encryption
|
||||
I (939) flash_encrypt: Disable UART bootloader cache...
|
||||
W (952) flash_encrypt: Not disabling JTAG - SECURITY COMPROMISED
|
||||
I (965) efuse: BURN BLOCK0
|
||||
I (970) efuse: BURN BLOCK0 - OK (write block == read block)
|
||||
I (973) efuse: Batch mode. Prepared fields are committed
|
||||
I (1063) esp_image: segment 0: paddr=00002020 vaddr=4ffb6240 size=03870h ( 14448)
|
||||
I (1132) esp_image: segment 1: paddr=00005898 vaddr=4ffac2c0 size=0179ch ( 6044)
|
||||
I (1200) esp_image: segment 2: paddr=0000703c vaddr=4ffaefc0 size=04ed8h ( 20184)
|
||||
I (1725) flash_encrypt: bootloader encrypted successfully
|
||||
I (1769) flash_encrypt: partition table encrypted and loaded successfully
|
||||
I (1851) esp_image: segment 0: paddr=00010020 vaddr=40030020 size=0d1e8h ( 53736) map
|
||||
I (1919) esp_image: segment 1: paddr=0001d210 vaddr=30100000 size=00044h ( 68)
|
||||
I (1988) esp_image: segment 2: paddr=0001d25c vaddr=4ff20000 size=02dbch ( 11708)
|
||||
I (2056) esp_image: segment 3: paddr=00020020 vaddr=40000020 size=21834h (137268) map
|
||||
I (2133) esp_image: segment 4: paddr=0004185c vaddr=4ff22dbc size=094e8h ( 38120)
|
||||
I (2202) esp_image: segment 5: paddr=0004ad4c vaddr=4ff2c300 size=044ech ( 17644)
|
||||
I (2315) flash_encrypt: Encrypting partition 0 at offset 0x10000 (length 0x3f260)...
|
||||
I (4978) flash_encrypt: Done encrypting
|
||||
I (4992) efuse: BURN BLOCK0
|
||||
I (4997) efuse: BURN BLOCK0 - OK (all write block bits are set)
|
||||
I (5001) flash_encrypt: Flash encryption completed
|
||||
I (5005) boot: Resetting with flash encryption enabled...
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
.. already_en_enc
|
||||
|
||||
.. code-block:: none
|
||||
@@ -152,3 +218,77 @@
|
||||
I (595) main_task: Returned from app_main()
|
||||
|
||||
------
|
||||
|
||||
|
||||
.. already_en_enc_km
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ESP-ROM:esp32p4-eco5-20250430
|
||||
Build:Apr 30 2025
|
||||
rst:0x3 (SW_SYS_RESET),boot:0xc (SPI_FAST_FLASH_BOOT)
|
||||
Core0 Saved PC:0x4ffb0910
|
||||
Core1 Saved PC:0x4fc05fa4
|
||||
SPI mode:DIO, clock div:1
|
||||
load:0x4ffb6240,len:0x3870
|
||||
load:0x4ffac2c0,len:0x179c
|
||||
load:0x4ffaefc0,len:0x4ed8
|
||||
entry 0x4ffac2ca
|
||||
I (37) boot: ESP-IDF v6.0-dev-2918-g6629f96afca-dirt 2nd stage bootloader
|
||||
I (38) boot: compile time Oct 14 2025 08:50:07
|
||||
I (38) boot: Multicore bootloader
|
||||
I (84) boot: chip revision: v3.0
|
||||
I (87) boot: efuse block revision: v1.0
|
||||
I (106) boot.esp32p4: SPI Speed : 80MHz
|
||||
I (110) boot.esp32p4: SPI Mode : DIO
|
||||
I (113) boot.esp32p4: SPI Flash Size : 2MB
|
||||
I (121) boot: Enabling RNG early entropy source...
|
||||
I (155) boot: Partition Table:
|
||||
I (158) boot: ## Label Usage Type ST Offset Length
|
||||
I (172) boot: 0 factory factory app 00 00 00010000 00150000
|
||||
I (186) boot: 1 storage Unknown data 01 81 00160000 00050000
|
||||
I (193) boot: End of partition table
|
||||
I (287) esp_image: segment 0: paddr=00010020 vaddr=40030020 size=0d1e8h ( 53736) map
|
||||
I (355) esp_image: segment 1: paddr=0001d210 vaddr=30100000 size=00044h ( 68) load
|
||||
I (422) esp_image: segment 2: paddr=0001d25c vaddr=4ff20000 size=02dbch ( 11708) load
|
||||
I (491) esp_image: segment 3: paddr=00020020 vaddr=40000020 size=21834h (137268) map
|
||||
I (567) esp_image: segment 4: paddr=0004185c vaddr=4ff22dbc size=094e8h ( 38120) load
|
||||
I (635) esp_image: segment 5: paddr=0004ad4c vaddr=4ff2c300 size=044ech ( 17644) load
|
||||
I (750) boot: Loaded app from partition at offset 0x10000
|
||||
I (752) boot: Checking flash encryption...
|
||||
I (769) flash_encrypt: flash encryption is enabled (1 plaintext flashes left)
|
||||
I (776) boot: Disabling RNG early entropy source...
|
||||
W (847) pmu_pvt: blk_version is less than 2, pvt auto dbias init not supported in efuse.
|
||||
I (855) cpu_start: Multicore app
|
||||
I (890) cpu_start: GPIO 38 and 37 are used as console UART I/O pins
|
||||
I (901) cpu_start: Pro cpu start user code
|
||||
I (905) cpu_start: cpu freq: 400000000 Hz
|
||||
I (914) app_init: Application information:
|
||||
I (918) app_init: Project name: crypto_test
|
||||
I (922) app_init: App version: qa-test-esp32c61-master-2025070
|
||||
I (928) app_init: Compile time: Oct 14 2025 08:50:07
|
||||
I (933) app_init: ELF file SHA256: 847005dd4...
|
||||
I (938) app_init: ESP-IDF: v6.0-dev-2918-g6629f96afca-dirt
|
||||
I (949) efuse_init: Min chip rev: v3.0
|
||||
I (953) efuse_init: Max chip rev: v3.99
|
||||
I (957) efuse_init: Chip rev: v3.0
|
||||
I (1126) heap_init: Initializing. RAM available for dynamic allocation:
|
||||
I (1137) heap_init: At 4FF33B20 len 000874A0 (541 KiB): RAM
|
||||
I (1143) heap_init: At 4FFBAFC0 len 00004BF0 (18 KiB): RAM
|
||||
I (1153) heap_init: At 50108080 len 00007F80 (31 KiB): RTCRAM
|
||||
I (1163) heap_init: At 30100044 len 00001FBC (7 KiB): TCM
|
||||
I (1261) spi_flash: detected chip: gd
|
||||
I (1264) spi_flash: flash io: dio
|
||||
W (1267) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
|
||||
W (1293) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)
|
||||
I (1357) main_task: Started on CPU0
|
||||
I (1407) main_task: Calling app_main()
|
||||
I (1407) main_task: Returned from app_main()
|
||||
|
||||
Example to check Flash Encryption status
|
||||
This is esp32p4 chip with 2 CPU core(s), WiFi, silicon revision v0.0, 2MB external flash
|
||||
FLASH_CRYPT_CNT eFuse value is 1
|
||||
Flash encryption feature is enabled in DEVELOPMENT mode
|
||||
|
||||
|
||||
------
|
||||
|
||||
@@ -93,7 +93,35 @@ flash 加密操作由 {IDF_TARGET_NAME} 上的多个 eFuse 控制,具体 eFuse
|
||||
- 7
|
||||
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 and SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
.. list-table:: flash 加密过程中使用的 eFuses
|
||||
:widths: 25 40 10
|
||||
:header-rows: 0
|
||||
|
||||
* - **eFuse**
|
||||
- **描述**
|
||||
- **位深**
|
||||
* - ``BLOCK_KEYN``
|
||||
- AES 密钥存储,N 在 0-5 之间。当使用基于密钥管理器的密钥时,此 eFuse 不被使用。
|
||||
- XTS_AES_128 有一个 256 位密钥块,XTS_AES_256 有两个 256 位密钥块(共 512 位)。
|
||||
* - ``KEY_PURPOSE_N``
|
||||
- 控制 eFuse 块 ``BLOCK_KEYN`` 的目的,其中 N 在 0-5 之间。可能的值:``2`` 代表 ``XTS_AES_256_KEY_1``,``3`` 代表 ``XTS_AES_256_KEY_2``,``4`` 代表 ``XTS_AES_128_KEY``。最终 AES 密钥是基于其中一个或两个目的 eFuses 值推导。有关各种可能的组合,请参阅 *{IDF_TARGET_NAME} 技术参考手册* > *外部内存加密和解密(XTS_AES)* [`PDF <{IDF_TARGET_TRM_CN_URL}#extmemencr>`__]。使用基于密钥管理器的密钥启用 flash 加密时,此 eFuse 不被使用。
|
||||
- 4
|
||||
* - ``KM_XTS_KEY_LENGTH_256``
|
||||
- 使用基于密钥管理器的密钥启用 flash 加密时,此 eFuse 用于控制 XTS-AES 密钥的长度。将此 eFuse 设置为 1 表示使用 128 位密钥,设置为 0 表示使用 256 位密钥。使用基于 eFuse 的密钥启用 flash 加密时,此 eFuse 字段不被使用。
|
||||
- 1
|
||||
* - ``FORCE_USE_KEY_MANAGER_KEY``
|
||||
- 使用基于密钥管理器的密钥启用 flash 加密时,此 eFuse 用于强制密钥管理器使用 XTS-AES 密钥。将此 eFuse 的第 1 位设置为 1 以使用基于密钥管理器的密钥。使用基于 eFuse 的密钥启用 flash 加密时,此 eFuse 字段不被使用。
|
||||
- 1
|
||||
* - ``DIS_DOWNLOAD_MANUAL_ENCRYPT``
|
||||
- 设置后,在下载启动模式下禁用 flash 加密。
|
||||
- 1
|
||||
* - ``{IDF_TARGET_CRYPT_CNT}``
|
||||
- 设置 SPI 启动模式后,可启用加密和解密。如果在 eFuse 中设置了 1 或 3 个比特位,则启用该功能,否则将禁用。
|
||||
- 3
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
.. list-table:: flash 加密过程中使用的 eFuses
|
||||
:widths: 25 40 10
|
||||
@@ -115,7 +143,35 @@ flash 加密操作由 {IDF_TARGET_NAME} 上的多个 eFuse 控制,具体 eFuse
|
||||
- 设置 SPI 启动模式后,可启用加密和解密。如果在 eFuse 中设置了 1 或 3 个比特位,则启用该功能,否则将禁用。
|
||||
- 3
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK and SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
.. list-table:: flash 加密过程中使用的 eFuses
|
||||
:widths: 25 40 10
|
||||
:header-rows: 0
|
||||
|
||||
* - **eFuse**
|
||||
- **描述**
|
||||
- **位深**
|
||||
* - ``BLOCK_KEYN``
|
||||
- AES 密钥存储,N 在 0-5 之间。当使用基于密钥管理器的密钥时,此 eFuse 不被使用。
|
||||
- 256 位密钥块。
|
||||
* - ``KEY_PURPOSE_N``
|
||||
- 控制 eFuse 块 ``BLOCK_KEYN`` 的目的,其中 N 在 0 到 5 之间。对于 flash 加密,唯一的有效值是 4,代表 ``XTS_AES_128_KEY``。使用基于密钥管理器的密钥启用 flash 加密时,此 eFuse 不被使用。
|
||||
- 4
|
||||
* - ``KM_XTS_KEY_LENGTH_256``
|
||||
- 使用基于密钥管理器的密钥启用 flash 加密时,此 eFuse 用于控制 XTS-AES 密钥的长度。将此 eFuse 设置为 1 表示使用 128 位密钥,设置为 0 表示使用 256 位密钥。使用基于 eFuse 的密钥启用 flash 加密时,此 eFuse 字段不被使用。
|
||||
- 1
|
||||
* - ``FORCE_USE_KEY_MANAGER_KEY``
|
||||
- 使用基于密钥管理器的密钥启用 flash 加密时,此 eFuse 用于强制密钥管理器使用 XTS-AES 密钥。将此 eFuse 的第 1 位设置为 1 以使用基于密钥管理器的密钥。使用基于 eFuse 的密钥启用 flash 加密时,此 eFuse 字段不被使用。
|
||||
- 1
|
||||
* - ``DIS_DOWNLOAD_MANUAL_ENCRYPT``
|
||||
- 设置后,则在下载引导模式时禁用 flash 加密。
|
||||
- 1
|
||||
* - ``{IDF_TARGET_CRYPT_CNT}``
|
||||
- 设置 SPI 启动模式后,可启用加密和解密。如果在 eFuse 中设置 1 或 3 个比特位,则启用该功能,否则将禁用。
|
||||
- 3
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK and not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
.. list-table:: flash 加密过程中使用的 eFuses
|
||||
:widths: 25 40 10
|
||||
@@ -195,7 +251,35 @@ flash 的加密过程
|
||||
|
||||
8. 重新启动设备以开始执行加密镜像。二级引导加载程序调用 flash 解密块来解密 flash 内容,然后将解密的内容加载到 IRAM 中。
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 and SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
1. 第一次开机复位时,flash 中的所有数据都是未加密的(明文)。一级 (ROM) 引导加载程序加载二级引导加载程序。
|
||||
|
||||
2. 二级引导加载程序将读取 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值 (``0b000``)。因为该值为 0(偶数位),二级引导加载程序将配置并启用 flash 加密块。关于 flash 加密块的更多信息,请参考 *{IDF_TARGET_NAME} 技术参考手册* > *eFuse 控制器 (eFuse)* > *手动加密块* [`PDF <{IDF_TARGET_TRM_CN_URL}#efuse>`__]。
|
||||
|
||||
3. 二级引导加载程序首先检查 eFuse 中是否已经存在有效密钥(例如用 espefuse 工具烧写的密钥)(若打算使用基于 eFuse 的密钥启用 flash 加密),或者检查 flash 内存地址 0x0 和 0x1000 处是否存在有效的密钥恢复信息(若打算使用基于密钥管理器的密钥启用 flash 加密),若存在则跳过密钥生成步骤,并将该密钥用于 flash 加密过程。
|
||||
|
||||
4. 否则,如果使用基于 eFuse 的密钥,二级引导加载程序将使用 RNG(随机数发生器)模块生成 256 位或 512 位的密钥(具体位数取决于 :ref:`生成的 XTS-AES 密钥的大小 <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`),然后将其分别写入一个或两个 `BLOCK_KEYN` eFuse 中。软件也为存储密钥的块更新了 ``KEY_PURPOSE_N``。由于上述一个或两个 ``BLOCK_KEYN`` eFuse 已设置了读保护和写保护位,因此无法通过软件访问密钥。``KEY_PURPOSE_N`` 字段也受写保护。如果使用基于密钥管理器的密钥,二级引导加载程序则将密钥恢复信息写入 flash 内存地址 0x0,随后对 ``KM_XTS_KEY_LENGTH_256`` 和 ``FORCE_USE_KEY_MANAGER_KEY`` eFuse 进行编程。flash 加密操作完全在硬件中完成,无法通过软件访问密钥。
|
||||
|
||||
5. flash 加密块将加密 flash 的内容(二级引导加载程序、应用程序、以及标有”加密”标志的分区)。就地加密可能会耗些时间(对于大分区最多需要一分钟)。
|
||||
|
||||
6. 二级引导加载程序将在 ``{IDF_TARGET_CRYPT_CNT}`` (0b001) 中设置第一个可用位来对已加密的 flash 内容进行标记。设置奇数位。
|
||||
|
||||
7. 对于 :ref:`flash-enc-development-mode`,二级引导加载程序允许 UART 引导加载程序重新烧录加密后的二进制文件。同时,``{IDF_TARGET_CRYPT_CNT}`` eFuse 位不受写入保护。此外,二级引导加载程序默认置位以下 eFuse 位:
|
||||
|
||||
.. list::
|
||||
|
||||
:esp32s2: - ``DIS_BOOT_REMAP``
|
||||
- ``DIS_DOWNLOAD_ICACHE``
|
||||
- ``DIS_DOWNLOAD_DCACHE``
|
||||
- ``HARD_DIS_JTAG``
|
||||
- ``DIS_LEGACY_SPI_BOOT``
|
||||
|
||||
8. 对于 :ref:`flash-enc-release-mode`,二级引导加载程序设置所有在开发模式下设置的 eFuse 位以及 ``DIS_DOWNLOAD_MANUAL_ENCRYPT``。它还写保护 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 位。要修改此行为,请参阅 :ref:`uart-bootloader-encryption`。
|
||||
|
||||
9. 重新启动设备以开始执行加密镜像。二级引导加载程序调用 flash 解密块来解密 flash 内容,然后将解密的内容加载到 IRAM 中。
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
1. 第一次开机复位时,flash 中的所有数据都是未加密的(明文)。一级 (ROM) 引导加载程序加载二级引导加载程序。
|
||||
|
||||
@@ -203,7 +287,7 @@ flash 的加密过程
|
||||
|
||||
3. 二级引导加载程序首先检查 eFuse 中是否已经存在有效密钥(例如用 espefuse 工具烧写的密钥),如果存在,则会跳过密钥生成,并将该密钥用于 flash 加密过程。否则,二级引导加载程序使用 RNG(随机数发生器)模块生成一个 256 位或 512 位的密钥,具体位数取决于 :ref:`生成的 XTS-AES 密钥的大小 <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`,然后将其分别写入一个或两个 `BLOCK_KEYN` eFuse 中。软件也为存储密钥的块更新了 ``KEY_PURPOSE_N``。由于上述一个或两个 ``BLOCK_KEYN`` eFuse 已设置了读保护和写保护位,因此无法通过软件访问密钥。``KEY_PURPOSE_N`` 字段也受写保护。flash 加密操作完全在硬件中完成,无法通过软件访问密钥。
|
||||
|
||||
4. flash 加密块将加密 flash 的内容(二级引导加载程序、应用程序、以及标有“加密”标志的分区)。就地加密可能会耗些时间(对于大分区最多需要一分钟)。
|
||||
4. flash 加密块将加密 flash 的内容(二级引导加载程序、应用程序、以及标有”加密”标志的分区)。就地加密可能会耗些时间(对于大分区最多需要一分钟)。
|
||||
|
||||
5. 二级引导加载程序将在 ``{IDF_TARGET_CRYPT_CNT}`` (0b001) 中设置第一个可用位来对已加密的 flash 内容进行标记。设置奇数位。
|
||||
|
||||
@@ -217,27 +301,49 @@ flash 的加密过程
|
||||
- ``HARD_DIS_JTAG``
|
||||
- ``DIS_LEGACY_SPI_BOOT``
|
||||
|
||||
7. 对于 :ref:`flash-enc-release-mode`,二级引导加载程序设置所有在开发模式下设置的 eFuse 位。它还写保护 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 位。要修改此行为,请参阅 :ref:`uart-bootloader-encryption`。
|
||||
7. 对于 :ref:`flash-enc-release-mode`,二级引导加载程序设置所有在开发模式下设置的 eFuse 位以及 ``DIS_DOWNLOAD_MANUAL_ENCRYPT``。它还写保护 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 位。要修改此行为,请参阅 :ref:`uart-bootloader-encryption`。
|
||||
|
||||
8. 重新启动设备以开始执行加密镜像。二级引导加载程序调用 flash 解密块来解密 flash 内容,然后将解密的内容加载到 IRAM 中。
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK and SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
1. 第一次开机复位时,flash 中的所有数据都是未加密的(明文)。一级 (ROM) 引导加载程序加载二级引导加载程序。
|
||||
|
||||
2. 二级引导加载程序将读取 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值 (``0b000``)。因为该值为 0(偶数位),二级引导加载程序将配置并启用 flash 加密块。关于 flash 加密块的更多信息,请参考 `{IDF_TARGET_NAME} 技术参考手册 <{IDF_TARGET_TRM_CN_URL}>`_。
|
||||
|
||||
3. 二级引导加载程序首先检查 eFuse 中是否已经存在有效密钥(例如用 espefuse 工具烧写的密钥)(若打算使用基于 eFuse 的密钥启用 flash 加密),或者检查 flash 内存地址 0x0 和 0x1000 处是否存在有效的密钥恢复信息(若打算使用基于密钥管理器的密钥启用 flash 加密),若存在则跳过密钥生成步骤,并将该密钥用于 flash 加密过程。
|
||||
|
||||
4. 否则,如果使用基于 eFuse 的密钥,二级引导加载程序将使用 RNG(随机数发生器)模块生成一个 256 位密钥,然后将其写入一个 `BLOCK_KEYN` eFuse。软件也为存储密钥的块更新了 ``KEY_PURPOSE_N``。由于该 ``BLOCK_KEYN`` eFuse 已设置了读保护和写保护位,因此无法通过软件访问密钥。``KEY_PURPOSE_N`` 字段也受写保护。如果使用基于密钥管理器的密钥,二级引导加载程序则将密钥恢复信息写入 flash 内存地址 0x0,随后对 ``KM_XTS_KEY_LENGTH_256`` 和 ``FORCE_USE_KEY_MANAGER_KEY`` eFuse 进行编程。flash 加密操作完全在硬件中完成,无法通过软件访问密钥。
|
||||
|
||||
5. flash 加密块将加密 flash 的内容(二级引导加载程序、应用程序、以及标有”加密”标志的分区)。就地加密可能会耗些时间(对于大分区最多需要一分钟)。
|
||||
|
||||
6. 二级引导加载程序将在 ``{IDF_TARGET_CRYPT_CNT}`` (0b001) 中设置第一个可用位来对已加密的 flash 内容进行标记。设置奇数位。
|
||||
|
||||
7. 对于 :ref:`flash-enc-development-mode`,二级引导加载程序允许 UART 引导加载程序重新烧录加密后的二进制文件。同时,``{IDF_TARGET_CRYPT_CNT}`` eFuse 位不受写入保护。此外,默认情况下,二级引导加载程序设置 ``DIS_DOWNLOAD_ICACHE``、 ``DIS_PAD_JTAG``、 ``DIS_USB_JTAG`` 和 ``DIS_LEGACY_SPI_BOOT`` eFuse 位。
|
||||
|
||||
8. 对于 :ref:`flash-enc-release-mode`,二级引导加载程序设置所有在开发模式下设置的 eFuse 位以及 ``DIS_DOWNLOAD_MANUAL_ENCRYPT``。它还写保护 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 位。要修改此行为,请参阅 :ref:`uart-bootloader-encryption`。
|
||||
|
||||
9. 重新启动设备以开始执行加密镜像。二级引导加载程序调用 flash 解密块来解密 flash 内容,然后将解密的内容加载到 IRAM 中。
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
|
||||
1. 第一次开机复位时,flash 中的所有数据都是未加密的(明文)。一级 (ROM) 引导加载程序加载二级引导加载程序。
|
||||
|
||||
2. 二级引导加载程序将读取 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值 (``0b000``)。因为该值为 0(偶数位),二级引导加载程序将配置并启用 flash 加密块。关于 flash 加密块的更多信息,请参考 `{IDF_TARGET_NAME} 技术参考手册 <{IDF_TARGET_TRM_CN_URL}>`_。
|
||||
|
||||
3. 二级引导加载程序使用 RNG(随机数发生器)模块生成 256 位密钥,然后将其写入 `BLOCK_KEYN` eFuse。软件也为存储密钥的块更新了 ``KEY_PURPOSE_N``。由于 ``BLOCK_KEYN`` eFuse 已设置了读保护和写保护位,因此无法通过软件访问密钥。``KEY_PURPOSE_N`` 字段也受写保护。flash 加密操作完全在硬件中完成,无法通过软件访问密钥。如果 eFuse 中已经存在有效密钥(例如用 espefuse 工具烧写的密钥),则会跳过密钥生成,并将该密钥用于 flash 加密过程。
|
||||
3. 二级引导加载程序首先检查 eFuse 中是否已经存在有效密钥(例如用 espefuse 工具烧写的密钥),如果存在,则会跳过密钥生成,并将该密钥用于 flash 加密过程。
|
||||
|
||||
4. flash 加密块将加密 flash 的内容(二级引导加载程序、应用程序、以及标有“加密”标志的分区)。就地加密可能会耗些时间(对于大分区最多需要一分钟)。
|
||||
4. 否则,二级引导加载程序使用 RNG(随机数发生器)模块生成 256 位密钥,然后将其写入 `BLOCK_KEYN` eFuse。软件也为存储密钥的块更新了 ``KEY_PURPOSE_N``。由于 ``BLOCK_KEYN`` eFuse 已设置了读保护和写保护位,因此无法通过软件访问密钥。``KEY_PURPOSE_N`` 字段也受写保护。flash 加密操作完全在硬件中完成,无法通过软件访问密钥。
|
||||
|
||||
5. 二级引导加载程序将在 ``{IDF_TARGET_CRYPT_CNT}`` (0b001) 中设置第一个可用位来对已加密的 flash 内容进行标记。设置奇数位。
|
||||
5. flash 加密块将加密 flash 的内容(二级引导加载程序、应用程序、以及标有”加密”标志的分区)。就地加密可能会耗些时间(对于大分区最多需要一分钟)。
|
||||
|
||||
6. 对于 :ref:`flash-enc-development-mode`,二级引导加载程序允许 UART 引导加载程序重新烧录加密后的二进制文件。同时,``{IDF_TARGET_CRYPT_CNT}`` eFuse 位不受写入保护。此外,默认情况下,二级引导加载程序设置 ``DIS_DOWNLOAD_ICACHE``、 ``DIS_PAD_JTAG``、 ``DIS_USB_JTAG`` 和 ``DIS_LEGACY_SPI_BOOT`` eFuse 位。
|
||||
6. 二级引导加载程序将在 ``{IDF_TARGET_CRYPT_CNT}`` (0b001) 中设置第一个可用位来对已加密的 flash 内容进行标记。设置奇数位。
|
||||
|
||||
7. 对于 :ref:`flash-enc-release-mode`,二级引导加载程序设置所有在开发模式下设置的 eFuse 位以及 ``DIS_DOWNLOAD_MANUAL_ENCRYPT``。它还写保护 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 位。要修改此行为,请参阅 :ref:`uart-bootloader-encryption`。
|
||||
7. 对于 :ref:`flash-enc-development-mode`,二级引导加载程序允许 UART 引导加载程序重新烧录加密后的二进制文件。同时,``{IDF_TARGET_CRYPT_CNT}`` eFuse 位不受写入保护。此外,默认情况下,二级引导加载程序设置 ``DIS_DOWNLOAD_ICACHE``、 ``DIS_PAD_JTAG``、 ``DIS_USB_JTAG`` 和 ``DIS_LEGACY_SPI_BOOT`` eFuse 位。
|
||||
|
||||
8. 重新启动设备以开始执行加密镜像。二级引导加载程序调用 flash 解密块来解密 flash 内容,然后将解密的内容加载到 IRAM 中。
|
||||
8. 对于 :ref:`flash-enc-release-mode`,二级引导加载程序设置所有在开发模式下设置的 eFuse 位以及 ``DIS_DOWNLOAD_MANUAL_ENCRYPT``。它还写保护 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 位。要修改此行为,请参阅 :ref:`uart-bootloader-encryption`。
|
||||
|
||||
9. 重新启动设备以开始执行加密镜像。二级引导加载程序调用 flash 解密块来解密 flash 内容,然后将解密的内容加载到 IRAM 中。
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
|
||||
@@ -301,6 +407,7 @@ flash 加密设置
|
||||
:esp32: - :ref:`选择 UART ROM 下载模式 <CONFIG_SECURE_UART_ROM_DL_MODE>` (默认是 **启用**)。请注意,对于 ESP32 芯片,该选项仅在 :ref:`CONFIG_ESP32_REV_MIN` 级别设置为 3 时 (ESP32 V3) 可用。
|
||||
:not esp32: - :ref:`选择 UART ROM 下载模式 <CONFIG_SECURE_UART_ROM_DL_MODE>` (默认是 **启用**)。
|
||||
:SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS: - 设置 :ref:`生成的 XTS-AES 密钥大小 <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`。
|
||||
:SOC_KEY_MANAGER_SUPPORTED: - :ref:`选择 Flash 加密密钥的密钥来源 <CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE>`。
|
||||
- :ref:`选择适当详细程度的引导加载程序日志 <CONFIG_BOOTLOADER_LOG_LEVEL>`。
|
||||
- 保存配置并退出。
|
||||
|
||||
@@ -316,9 +423,23 @@ flash 加密设置
|
||||
|
||||
这个命令不包括任何应该写入 flash 分区的用户文件。请在运行此命令前手动写入这些文件,否则在写入前应单独对这些文件进行加密。
|
||||
|
||||
该命令将向 flash 写入未加密的镜像:二级引导加载程序、分区表和应用程序。烧录完成后,{IDF_TARGET_NAME} 将复位。在下一次启动时,二级引导加载程序会加密:二级引导加载程序、应用程序分区和标记为“加密”的分区,然后复位。就地加密可能需要时间,对于大分区最多需要一分钟。之后,应用程序在运行时解密并执行命令。
|
||||
该命令将向 flash 写入未加密的镜像:二级引导加载程序、分区表和应用程序。烧录完成后,{IDF_TARGET_NAME} 将复位。在下一次启动时,二级引导加载程序会加密:二级引导加载程序、应用程序分区和标记为”加密”的分区,然后复位。就地加密可能需要时间,对于大分区最多需要一分钟。之后,应用程序在运行时解密并执行命令。
|
||||
|
||||
下面是启用 flash 加密后 {IDF_TARGET_NAME} 首次启动时的样例输出:
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
下面是使用基于密钥管理器的密钥启用 flash 加密后 {IDF_TARGET_NAME} 首次启动时的样例输出:
|
||||
|
||||
.. include:: {IDF_TARGET_PATH_NAME}_log.inc
|
||||
:start-after: first_boot_enc_km
|
||||
:end-before: ------
|
||||
|
||||
下面是 {IDF_TARGET_NAME} 后续启动时的样例输出,仅说明 flash 加密已启用(ESP-ROM 日志会提示正在使用基于密钥管理器的密钥):
|
||||
|
||||
.. include:: {IDF_TARGET_PATH_NAME}_log.inc
|
||||
:start-after: already_en_enc_km
|
||||
:end-before: ------
|
||||
|
||||
下面是使用基于 eFuse 的密钥启用 flash 加密后 {IDF_TARGET_NAME} 首次启动时的样例输出:
|
||||
|
||||
.. include:: {IDF_TARGET_PATH_NAME}_log.inc
|
||||
:start-after: first_boot_enc
|
||||
@@ -338,7 +459,7 @@ flash 加密设置
|
||||
使用主机生成的密钥
|
||||
""""""""""""""""""""""""
|
||||
|
||||
可在主机中预生成 flash 加密密钥,并将其烧录到 eFuse 密钥块中。这样,无需明文 flash 更新便可以在主机上预加密数据并将其烧录。该功能可在 :ref:`flash-enc-development-mode` 和 :ref:`flash-enc-release-mode` 两模式下使用。如果没有预生成的密钥,数据将以明文形式烧录,然后 {IDF_TARGET_NAME} 对数据进行就地加密。
|
||||
可在主机中预生成 flash 加密密钥,并将其编程到设备中。这样,无需明文 flash 更新便可以在主机上预加密数据并将其烧录。该功能可在 :ref:`flash-enc-development-mode` 和 :ref:`flash-enc-release-mode` 两模式下使用。如果没有预生成的密钥,数据将以明文形式烧录,然后 {IDF_TARGET_NAME} 对数据进行就地加密。
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -555,6 +676,72 @@ flash 加密设置
|
||||
|
||||
该命令将向 flash 写入未加密的镜像:二级引导加载程序、分区表和应用程序。烧录完成后,{IDF_TARGET_NAME} 将复位。在下一次启动时,二级引导加载程序会加密:二级引导加载程序、应用程序分区和标记为 ``加密`` 的分区,然后复位。就地加密可能需要时间,对于大的分区来说可能耗时一分钟。之后,应用程序在运行时被解密并执行。
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
如需使用主机生成的密钥并将其部署到设备的密钥管理器,请完成以下步骤:
|
||||
|
||||
1. 确保你的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
|
||||
请参考如何检查 :ref:`flash-encryption-status`。
|
||||
|
||||
2. 通过运行以下命令生成一个随机密钥:
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256
|
||||
|
||||
如果 :ref:`生成的 XTS-AES 密钥大小 <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>` 是 AES-128(256 位密钥):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py secure-generate-flash-encryption-key my_flash_encryption_key.bin
|
||||
|
||||
否则如果 :ref:`生成的 XTS-AES 密钥大小 <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>` 是 AES-256(512 位密钥):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py secure-generate-flash-encryption-key --keylen 512 my_flash_encryption_key.bin
|
||||
|
||||
|
||||
.. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py secure-generate-flash-encryption-key my_flash_encryption_key.bin
|
||||
|
||||
|
||||
3. **在第一次加密启动前**,使用密钥管理器的 AES 部署模式,通过初始化密钥和辅助密钥将密钥部署到设备的密钥管理器中。
|
||||
|
||||
4. 部署过程将为已部署的密钥生成密钥恢复信息。使用以下命令将该信息存储到 flash 地址 0x0:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
esptool --port PORT --baud BAUD write-flash 0x0 key_recovery_info.bin
|
||||
|
||||
如果未部署密钥就在启用 flash 加密后启动设备,{IDF_TARGET_NAME} 将生成并部署一个软件无法访问或修改的随机密钥。
|
||||
|
||||
.. note::
|
||||
|
||||
这个命令不包括任何应该被写入 flash 上的分区的用户文件。请在运行此命令前手动写入这些文件,否则在写入前应单独对这些文件进行加密。
|
||||
|
||||
5. 在 :ref:`项目配置菜单 <project-configuration-menu>` 中进行如下设置:
|
||||
|
||||
- :ref:`启动时启用 flash 加密功能 <CONFIG_SECURE_FLASH_ENC_ENABLED>`
|
||||
- :ref:`选择加密模式 <CONFIG_SECURE_FLASH_ENCRYPTION_MODE>` (默认为 **开发模式**)
|
||||
- :ref:`选择 flash 加密密钥来源为密钥管理器 <CONFIG_SECURE_FLASH_ENCRYPTION_KEY_SOURCE>`
|
||||
- :ref:`选择适当详细程度的引导加载程序日志 <CONFIG_BOOTLOADER_LOG_LEVEL>`
|
||||
- 保存配置并退出。
|
||||
|
||||
启用 flash 加密将增大引导加载程序,因而可能需更新分区表偏移量。请参考 :ref:`引导加载程序大小 <bootloader-size>`。
|
||||
|
||||
6. 运行以下命令来构建并烧录完整的镜像:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
idf.py flash monitor
|
||||
|
||||
.. note::
|
||||
|
||||
这个命令不包括任何应该被写入 flash 上的分区的用户文件。请在运行此命令前手动写入这些文件,否则在写入前应单独对这些文件进行加密。
|
||||
|
||||
一旦在量产模式下启用 flash 加密,引导加载程序将写保护 ``{IDF_TARGET_CRYPT_CNT}`` eFuse。
|
||||
|
||||
请使用 :ref:`OTA 方案 <updating-encrypted-flash-ota>` 对字段中的明文进行后续更新。
|
||||
@@ -828,7 +1015,9 @@ flash 加密的要点
|
||||
|
||||
:esp32: - flash 加密算法采用的是 AES-256,其中密钥随着 flash 的每个 32 字节块的偏移地址“调整”。这意味着,每个 32 字节块(2 个连续的 16 字节 AES 块)使用从 flash 加密密钥中产生的一个特殊密钥进行加密。
|
||||
|
||||
:esp32s2 or esp32s3: - 使用 XTS-AES-128 或 XTS-AES-256 加密 flash。flash 加密密钥分别为 256 位和 512 位,存储于芯片内部一个或两个 ``BLOCK_KEYN`` eFuse 中,并(默认)受保护,防止软件访问。
|
||||
:SOC_FLASH_ENCRYPTION_XTS_AES_256 and SOC_KEY_MANAGER_SUPPORTED: - 使用 XTS-AES-128 或 XTS-AES-256 加密 flash。flash 加密密钥分别为 256 位和 512 位,若 flash 加密使用基于 eFuse 的密钥启用,则存储于芯片内部一个或两个 ``BLOCK_KEYN`` eFuse 中;若 flash 加密使用基于密钥管理器的密钥启用,则 flash 加密密钥存储于密钥管理器中,并(默认)受保护,防止软件访问。
|
||||
|
||||
:SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_KEY_MANAGER_SUPPORTED: - 使用 XTS-AES-128 或 XTS-AES-256 加密 flash。flash 加密密钥分别为 256 位和 512 位,存储于芯片内部一个或两个 ``BLOCK_KEYN`` eFuse 中,并(默认)受保护,防止软件访问。
|
||||
|
||||
:esp32c3: - 使用 XTS-AES-128 加密 flash。 flash 加密密钥为 256 位,存储于芯片内部的 ``BLOCK_KEYN`` eFuse 中,并(默认)受保护,防止软件访问。
|
||||
|
||||
@@ -1003,7 +1192,13 @@ JTAG 调试
|
||||
手动加密文件
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
手动加密或解密文件需要在 eFuse 中预烧录 flash 加密密钥(请参阅 :ref:`pregenerated-flash-encryption-key`)并在主机上保留一份副本。 如果 flash 加密配置在开发模式下,那么则不需要保留密钥的副本或遵循这些步骤,可以使用更简单的 :ref:`encrypt-partitions` 步骤。
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
手动加密或解密文件需要将 flash 加密密钥部署到密钥管理器或在 eFuse 中预烧录(请参阅 :ref:`pregenerated-flash-encryption-key`)并在主机上保留一份副本。如果 flash 加密配置在开发模式下,那么则不需要保留密钥的副本或遵循这些步骤,可以使用更简单的 :ref:`encrypt-partitions` 步骤。
|
||||
|
||||
.. only:: not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
手动加密或解密文件需要在 eFuse 中预烧录 flash 加密密钥(请参阅 :ref:`pregenerated-flash-encryption-key`)并在主机上保留一份副本。 如果 flash 加密配置在开发模式下,那么则不需要保留密钥的副本或遵循这些步骤,可以使用更简单的 :ref:`encrypt-partitions` 步骤。
|
||||
|
||||
密钥文件应该是单个原始二进制文件(例如:``key.bin``)。
|
||||
|
||||
|
||||
@@ -130,14 +130,52 @@
|
||||
|
||||
espsecure generate-flash-encryption-key --keylen 128 my_flash_encryption_key.bin
|
||||
|
||||
3. 将 flash 加密密钥烧录到 eFuse 中
|
||||
3. 将生成的 Flash 加密密钥编程到设备中
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
a. 如果打算使用 Key Manager 存储 Flash 加密密钥,请使用脚本 `generate_km_test_cases.py` 生成密钥部署参数,并使用该参数将密钥部署到 Key Manager 中。密钥部署到 Key Manager 后,使用以下命令将生成的密钥恢复信息存储到 flash 存储器地址 0x0 处:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
esptool --port PORT write-flash 0x0 key_recovery_info.bin
|
||||
|
||||
将密钥恢复信息存储到 flash 存储器后,还需要编程 ``KM_XTS_KEY_LENGTH_256`` 和 ``FORCE_USE_KEY_MANAGER_KEY`` eFuse。
|
||||
|
||||
.. warning::
|
||||
|
||||
这个操作 **无法回退**。
|
||||
|
||||
``FORCE_USE_KEY_MANAGER_KEY`` eFuse 的第 1 位用于强制使用基于 Key Manager 的 XTS-AES 密钥。
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
espefuse --port PORT burn-efuse FORCE_USE_KEY_MANAGER_KEY 2
|
||||
|
||||
``KM_XTS_KEY_LENGTH_256`` eFuse 用于控制基于 Key Manager 的 XTS-AES 密钥的长度。将该 eFuse 设置为 1 表示使用 128 位密钥,设置为 0 表示使用 256 位密钥。
|
||||
|
||||
如果使用 128 位密钥,将 ``KM_XTS_KEY_LENGTH_256`` eFuse 设置为 1。
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
espefuse --port PORT burn-efuse KM_XTS_KEY_LENGTH_256 1
|
||||
|
||||
如果使用 256 位密钥,将 ``KM_XTS_KEY_LENGTH_256`` eFuse 设置为 0。
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
espefuse --port PORT burn-efuse KM_XTS_KEY_LENGTH_256 0
|
||||
|
||||
b. 如需将 Flash 加密密钥存储在 eFuse 中,请运行以下命令:
|
||||
|
||||
.. only:: not SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
如需将 Flash 加密密钥存储在 eFuse 中,请运行以下命令:
|
||||
|
||||
.. warning::
|
||||
|
||||
这个操作 **无法回退**。
|
||||
|
||||
运行以下命令进行烧录:
|
||||
|
||||
.. only:: not SOC_FLASH_ENCRYPTION_XTS_AES
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -101,6 +101,25 @@ flash 加密最佳实践
|
||||
|
||||
详情请参阅 :doc:`../api-reference/peripherals/ecdsa` 及 :doc:`../api-reference/peripherals/ds`。
|
||||
|
||||
.. only:: SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
密钥管理器
|
||||
~~~~~~~~~~
|
||||
|
||||
{IDF_TARGET_NAME} 中的密钥管理器外设提供硬件辅助的 **密钥部署和恢复** 功能,适用于加密密钥。密钥通过硬件唯一密钥 (HUK) 与芯片绑定,该密钥对每块芯片唯一,从而确保密钥内容不会暴露在软件可访问的内存中。
|
||||
|
||||
密钥管理器支持以下加密外设的密钥管理::doc:`ECDSA <../api-reference/peripherals/ecdsa>`、:doc:`HMAC <../api-reference/peripherals/hmac>`、:doc:`数字签名 (DS) <../api-reference/peripherals/ds>` 以及 flash 加密。
|
||||
|
||||
详情请参阅 :doc:`../api-reference/peripherals/key_manager`。
|
||||
|
||||
密钥管理器最佳实践
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* 防止密钥管理器部署密钥的 ``key_recovery_info`` 遭受未授权修改或丢失。
|
||||
* 在成功部署密钥后,锁定密钥管理器相关的安全 eFuse,以防止重新部署同类型密钥。
|
||||
* 除非明确需要,否则在 flash 加密已启用的情况下,避免部署新的 XTS-AES 密钥。
|
||||
|
||||
|
||||
.. only:: SOC_MEMPROT_SUPPORTED or SOC_CPU_IDRAM_SPLIT_USING_PMP
|
||||
|
||||
内存保护
|
||||
|
||||
@@ -35,12 +35,12 @@ These parameters are used to derive and deploy the actual cryptographic key insi
|
||||
|
||||
### Hardware Required
|
||||
|
||||
This example requires an ESP32-C5 (Key Manager supported) development board.
|
||||
This example can be executed on any development board with a Espressif SOC chip supporting the Key Manager peripheral (see Supported Targets table above).
|
||||
|
||||
### Configure the Project
|
||||
|
||||
```bash
|
||||
idf.py set-target esp32c5
|
||||
idf.py set-target <chip_name>
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
@@ -283,8 +283,8 @@ The script generates:
|
||||
This example includes a pytest that can be run with the ESP-IDF pytest framework:
|
||||
|
||||
```bash
|
||||
# Run the test on ESP32-C5
|
||||
pytest --target esp32c5
|
||||
# Run the test on the target
|
||||
pytest --target <chip_name>
|
||||
```
|
||||
|
||||
The test verifies:
|
||||
|
||||
Reference in New Issue
Block a user