mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-30 20:51:41 +00:00 
			
		
		
		
	feat: enabled hmac and ds support in esp32h21
This commit enables support for HMAC and DS in ESP32H21
This commit is contained in:
		| @@ -0,0 +1,142 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #define ETS_DS_MAX_BITS 3072 | ||||||
|  |  | ||||||
|  | #define ETS_DS_IV_LEN 16 | ||||||
|  |  | ||||||
|  | /* Length of parameter 'C' stored in flash (not including IV) | ||||||
|  |  | ||||||
|  |    Comprises encrypted Y, M, rinv, md (32), mprime (4), length (4), padding (8) | ||||||
|  |  | ||||||
|  |    Note that if ETS_DS_MAX_BITS<4096, 'C' needs to be split up when writing to hardware | ||||||
|  | */ | ||||||
|  | #define ETS_DS_C_LEN ((ETS_DS_MAX_BITS * 3 / 8) + 32 + 8 + 8) | ||||||
|  |  | ||||||
|  | /* Encrypted ETS data. Recommended to store in flash in this format. | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  |     /* RSA LENGTH register parameters | ||||||
|  |      * (number of words in RSA key & operands, minus one). | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * This value must match the length field encrypted and stored in 'c', | ||||||
|  |      * or invalid results will be returned. (The DS peripheral will | ||||||
|  |      * always use the value in 'c', not this value, so an attacker can't | ||||||
|  |      * alter the DS peripheral results this way, it will just truncate or | ||||||
|  |      * extend the message and the resulting signature in software.) | ||||||
|  |      */ | ||||||
|  |     unsigned rsa_length; | ||||||
|  |  | ||||||
|  |     /* IV value used to encrypt 'c' */ | ||||||
|  |     uint8_t iv[ETS_DS_IV_LEN]; | ||||||
|  |  | ||||||
|  |     /* Encrypted Digital Signature parameters. Result of AES-CBC encryption | ||||||
|  |        of plaintext values. Includes an encrypted message digest. | ||||||
|  |     */ | ||||||
|  |     uint8_t c[ETS_DS_C_LEN]; | ||||||
|  | } ets_ds_data_t; | ||||||
|  |  | ||||||
|  | typedef enum { | ||||||
|  |     ETS_DS_OK, | ||||||
|  |     ETS_DS_INVALID_PARAM,   /* Supplied parameters are invalid */ | ||||||
|  |     ETS_DS_INVALID_KEY,     /* HMAC peripheral failed to supply key */ | ||||||
|  |     ETS_DS_INVALID_PADDING, /* 'c' decrypted with invalid padding */ | ||||||
|  |     ETS_DS_INVALID_DIGEST,  /* 'c' decrypted with invalid digest */ | ||||||
|  | } ets_ds_result_t; | ||||||
|  |  | ||||||
|  | void ets_ds_enable(void); | ||||||
|  |  | ||||||
|  | void ets_ds_disable(void); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * @brief Start signing a message (or padded message digest) using the Digital Signature peripheral | ||||||
|  |  * | ||||||
|  |  * - @param message Pointer to message (or padded digest) containing the message to sign. Should be | ||||||
|  |  *   (data->rsa_length + 1)*4 bytes long.  @param data Pointer to DS data. Can be a pointer to data | ||||||
|  |  *   in flash. | ||||||
|  |  * | ||||||
|  |  * Caller must have already called ets_ds_enable() and ets_hmac_calculate_downstream() before calling | ||||||
|  |  * this function, and is responsible for calling ets_ds_finish_sign() and then | ||||||
|  |  * ets_hmac_invalidate_downstream() afterwards. | ||||||
|  |  * | ||||||
|  |  * @return ETS_DS_OK if signature is in progress, ETS_DS_INVALID_PARAM if param is invalid, | ||||||
|  |  * EST_DS_INVALID_KEY if key or HMAC peripheral is configured incorrectly. | ||||||
|  |  */ | ||||||
|  | ets_ds_result_t ets_ds_start_sign(const void *message, const ets_ds_data_t *data); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * @brief Returns true if the DS peripheral is busy following a call to ets_ds_start_sign() | ||||||
|  |  * | ||||||
|  |  * A result of false indicates that a call to ets_ds_finish_sign() will not block. | ||||||
|  |  * | ||||||
|  |  * Only valid if ets_ds_enable() has been called. | ||||||
|  |  */ | ||||||
|  | bool ets_ds_is_busy(void); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* @brief Finish signing a message using the Digital Signature peripheral | ||||||
|  |  * | ||||||
|  |  * Must be called after ets_ds_start_sign(). Can use ets_ds_busy() to wait until | ||||||
|  |  * peripheral is no longer busy. | ||||||
|  |  * | ||||||
|  |  * - @param signature Pointer to buffer to contain the signature. Should be | ||||||
|  |  *   (data->rsa_length + 1)*4 bytes long. | ||||||
|  |  * - @param data Should match the 'data' parameter passed to ets_ds_start_sign() | ||||||
|  |  * | ||||||
|  |  * @param ETS_DS_OK if signing succeeded, ETS_DS_INVALID_PARAM if param is invalid, | ||||||
|  |  * ETS_DS_INVALID_DIGEST or ETS_DS_INVALID_PADDING if there is a problem with the | ||||||
|  |  * encrypted data digest or padding bytes (in case of ETS_DS_INVALID_PADDING, a | ||||||
|  |  * digest is produced anyhow.) | ||||||
|  |  */ | ||||||
|  | ets_ds_result_t ets_ds_finish_sign(void *signature, const ets_ds_data_t *data); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Plaintext parameters used by Digital Signature. | ||||||
|  |  | ||||||
|  |    Not used for signing with DS peripheral, but can be encrypted | ||||||
|  |    in-device by calling ets_ds_encrypt_params() | ||||||
|  | */ | ||||||
|  | typedef struct { | ||||||
|  |     uint32_t Y[ETS_DS_MAX_BITS / 32]; | ||||||
|  |     uint32_t M[ETS_DS_MAX_BITS / 32]; | ||||||
|  |     uint32_t Rb[ETS_DS_MAX_BITS / 32]; | ||||||
|  |     uint32_t M_prime; | ||||||
|  |     uint32_t length; | ||||||
|  | } ets_ds_p_data_t; | ||||||
|  |  | ||||||
|  | typedef enum { | ||||||
|  |     ETS_DS_KEY_HMAC, /* The HMAC key (as stored in efuse) */ | ||||||
|  |     ETS_DS_KEY_AES,  /* The AES key (as derived from HMAC key by HMAC peripheral in downstream mode) */ | ||||||
|  | } ets_ds_key_t; | ||||||
|  |  | ||||||
|  | /* @brief Encrypt DS parameters suitable for storing and later use with DS peripheral | ||||||
|  |  * | ||||||
|  |  * @param data Output buffer to store encrypted data, suitable for later use generating signatures. | ||||||
|  |  * @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time. | ||||||
|  |  * @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process is done and 'data' is stored. | ||||||
|  |  * @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the corresponding HMAC key will be stored to efuse and then permanently erased. | ||||||
|  |  * @param key_type Type of key stored in 'key' (either the AES-256 DS key, or an HMAC DS key from which the AES DS key is derived using HMAC peripheral) | ||||||
|  |  * | ||||||
|  |  * @return ETS_DS_INVALID_PARAM if any parameter is invalid, or ETS_DS_OK if 'data' is successfully generated from the input parameters. | ||||||
|  |  */ | ||||||
|  | ets_ds_result_t ets_ds_encrypt_params(ets_ds_data_t *data, const void *iv, const ets_ds_p_data_t *p_data, const void *key, ets_ds_key_t key_type); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @@ -56,6 +56,10 @@ | |||||||
| #include "esp32h2/rom/digital_signature.h" | #include "esp32h2/rom/digital_signature.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if CONFIG_IDF_TARGET_ESP32H21 | ||||||
|  | #include "esp32h21/rom/digital_signature.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #if CONFIG_IDF_TARGET_ESP32P4 | #if CONFIG_IDF_TARGET_ESP32P4 | ||||||
| #include "esp32p4/rom/digital_signature.h" | #include "esp32p4/rom/digital_signature.h" | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,3 +1,3 @@ | |||||||
| | Supported Targets | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | | Supported Targets | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | ||||||
| | ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | | ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,6 +36,10 @@ | |||||||
| #include "esp32c5/rom/digital_signature.h" | #include "esp32c5/rom/digital_signature.h" | ||||||
| #include "esp32c5/rom/aes.h" | #include "esp32c5/rom/aes.h" | ||||||
| #include "esp32c5/rom/sha.h" | #include "esp32c5/rom/sha.h" | ||||||
|  | #elif CONFIG_IDF_TARGET_ESP32H21 | ||||||
|  | #include "esp32h21/rom/digital_signature.h" | ||||||
|  | #include "esp32h21/rom/aes.h" | ||||||
|  | #include "esp32h21/rom/sha.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include "esp_ds.h" | #include "esp_ds.h" | ||||||
|   | |||||||
							
								
								
									
										188
									
								
								components/hal/esp32h21/include/hal/ds_ll.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								components/hal/esp32h21/include/hal/ds_ll.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /******************************************************************************* | ||||||
|  |  * NOTICE | ||||||
|  |  * The hal is not public api, don't use it in application code. | ||||||
|  |  ******************************************************************************/ | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "soc/hwcrypto_reg.h" | ||||||
|  | #include "soc/soc_caps.h" | ||||||
|  | #include "soc/pcr_struct.h" | ||||||
|  | #include "hal/ds_types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Enable the bus clock for Digital Signature peripheral module | ||||||
|  |  * | ||||||
|  |  * @param true to enable the module, false to disable the module | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_enable_bus_clock(bool enable) | ||||||
|  | { | ||||||
|  |     PCR.ds_conf.ds_clk_en = enable; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Reset the Digital Signature peripheral module | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_reset_register(void) | ||||||
|  | { | ||||||
|  |     PCR.ds_conf.ds_rst_en = 1; | ||||||
|  |     PCR.ds_conf.ds_rst_en = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void ds_ll_start(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(DS_SET_START_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Wait until DS peripheral has finished any outstanding operation. | ||||||
|  |  */ | ||||||
|  | static inline bool ds_ll_busy(void) | ||||||
|  | { | ||||||
|  |     return (REG_READ(DS_QUERY_BUSY_REG) > 0) ? true : false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Busy wait until the hardware is ready. | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_wait_busy(void) | ||||||
|  | { | ||||||
|  |     while (ds_ll_busy()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief In case of a key error, check what caused it. | ||||||
|  |  */ | ||||||
|  | static inline ds_key_check_t ds_ll_key_error_source(void) | ||||||
|  | { | ||||||
|  |     uint32_t key_error = REG_READ(DS_QUERY_KEY_WRONG_REG); | ||||||
|  |     if (key_error == 0) { | ||||||
|  |         return DS_NO_KEY_INPUT; | ||||||
|  |     } else { | ||||||
|  |         return DS_OTHER_WRONG; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Write the initialization vector to the corresponding register field. | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_configure_iv(const uint32_t *iv) | ||||||
|  | { | ||||||
|  |     for (size_t i = 0; i < (SOC_DS_KEY_PARAM_MD_IV_LENGTH / sizeof(uint32_t)); i++) { | ||||||
|  |         REG_WRITE(DS_IV_MEM + (i * 4) , iv[i]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Write the message which should be signed. | ||||||
|  |  * | ||||||
|  |  * @param msg Pointer to the message. | ||||||
|  |  * @param size Length of msg in bytes. It is the RSA signature length in bytes. | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_write_message(const uint8_t *msg, size_t size) | ||||||
|  | { | ||||||
|  |     memcpy((uint8_t*) DS_X_MEM, msg, size); | ||||||
|  |     asm volatile ("fence"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Write the encrypted private key parameters. | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_write_private_key_params(const uint8_t *encrypted_key_params) | ||||||
|  | { | ||||||
|  |     /* Note: as the internal peripheral still has RSA 4096 structure, | ||||||
|  |        but C is encrypted based on the actual max RSA length (ETS_DS_MAX_BITS), need to fragment it | ||||||
|  |        when copying to hardware... | ||||||
|  |  | ||||||
|  |        (note if ETS_DS_MAX_BITS == 4096, this should be the same as copying data->c to hardware in one fragment) | ||||||
|  |     */ | ||||||
|  |     typedef struct { uint32_t addr; size_t len; } frag_t; | ||||||
|  |     const frag_t frags[] = { | ||||||
|  |                             {DS_Y_MEM,  SOC_DS_SIGNATURE_MAX_BIT_LEN / 8}, | ||||||
|  |                             {DS_M_MEM,  SOC_DS_SIGNATURE_MAX_BIT_LEN / 8}, | ||||||
|  |                             {DS_RB_MEM, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8}, | ||||||
|  |                             {DS_BOX_MEM, DS_IV_MEM - DS_BOX_MEM}, | ||||||
|  |     }; | ||||||
|  |     const size_t NUM_FRAGS = sizeof(frags)/sizeof(frag_t); | ||||||
|  |     const uint8_t *from = encrypted_key_params; | ||||||
|  |  | ||||||
|  |     for (int i = 0; i < NUM_FRAGS; i++) { | ||||||
|  |         memcpy((uint8_t *)frags[i].addr, from, frags[i].len); | ||||||
|  |         asm volatile ("fence"); | ||||||
|  |         from += frags[i].len; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Begin signing procedure. | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_start_sign(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(DS_SET_CONTINUE_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief check the calculated signature. | ||||||
|  |  * | ||||||
|  |  * @return | ||||||
|  |  * - DS_SIGNATURE_OK if no issue is detected with the signature. | ||||||
|  |  * - DS_SIGNATURE_PADDING_FAIL if the padding of the private key parameters is wrong. | ||||||
|  |  * - DS_SIGNATURE_MD_FAIL if the message digest check failed. This means that the message digest calculated using | ||||||
|  |  *      the private key parameters fails, i.e., the integrity of the private key parameters is not protected. | ||||||
|  |  * - DS_SIGNATURE_PADDING_AND_MD_FAIL if both padding and message digest check fail. | ||||||
|  |  */ | ||||||
|  | static inline ds_signature_check_t ds_ll_check_signature(void) | ||||||
|  | { | ||||||
|  |     uint32_t result = REG_READ(DS_QUERY_CHECK_REG); | ||||||
|  |     switch(result) { | ||||||
|  |     case 0: | ||||||
|  |         return DS_SIGNATURE_OK; | ||||||
|  |     case 1: | ||||||
|  |         return DS_SIGNATURE_MD_FAIL; | ||||||
|  |     case 2: | ||||||
|  |         return DS_SIGNATURE_PADDING_FAIL; | ||||||
|  |     default: | ||||||
|  |         return DS_SIGNATURE_PADDING_AND_MD_FAIL; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Read the signature from the hardware. | ||||||
|  |  * | ||||||
|  |  * @param result The signature result. | ||||||
|  |  * @param size Length of signature result in bytes. It is the RSA signature length in bytes. | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_read_result(uint8_t *result, size_t size) | ||||||
|  | { | ||||||
|  |     memcpy(result, (uint8_t*) DS_Z_MEM, size); | ||||||
|  |     asm volatile ("fence"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Exit the signature operation. | ||||||
|  |  * | ||||||
|  |  * @note This does not deactivate the module. Corresponding clock/reset bits have to be triggered for deactivation. | ||||||
|  |  */ | ||||||
|  | static inline void ds_ll_finish(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(DS_SET_FINISH_REG, 1); | ||||||
|  |     ds_ll_wait_busy(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
							
								
								
									
										212
									
								
								components/hal/esp32h21/include/hal/hmac_ll.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								components/hal/esp32h21/include/hal/hmac_ll.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,212 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /******************************************************************************* | ||||||
|  |  * NOTICE | ||||||
|  |  * The hal is not public api, don't use it in application code. | ||||||
|  |  * See readme.md in soc/include/hal/readme.md | ||||||
|  |  ******************************************************************************/ | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
|  | #include "soc/system_reg.h" | ||||||
|  | #include "soc/hwcrypto_reg.h" | ||||||
|  | #include "soc/pcr_struct.h" | ||||||
|  | #include "hal/hmac_types.h" | ||||||
|  |  | ||||||
|  | #define SHA256_BLOCK_SZ 64 | ||||||
|  | #define SHA256_DIGEST_SZ 32 | ||||||
|  |  | ||||||
|  | #define EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG 6 | ||||||
|  | #define EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE 7 | ||||||
|  | #define EFUSE_KEY_PURPOSE_HMAC_UP 8 | ||||||
|  | #define EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL 5 | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Enable the bus clock for HMAC peripheral module | ||||||
|  |  * | ||||||
|  |  * @param true to enable the module, false to disable the module | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_enable_bus_clock(bool enable) | ||||||
|  | { | ||||||
|  |     PCR.hmac_conf.hmac_clk_en = enable; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Reset the HMAC peripheral module | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_reset_register(void) | ||||||
|  | { | ||||||
|  |     PCR.hmac_conf.hmac_rst_en = 1; | ||||||
|  |     PCR.hmac_conf.hmac_rst_en = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Makes the peripheral ready for use, after enabling it. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_start(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_SET_START_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Determine where the HMAC output should go. | ||||||
|  |  * | ||||||
|  |  * The HMAC peripheral can be configured to deliver its output to the user directly, or to deliver | ||||||
|  |  * the output directly to another peripheral instead, e.g. the Digital Signature peripheral. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_config_output(hmac_hal_output_t config) | ||||||
|  | { | ||||||
|  |     switch(config) { | ||||||
|  |     case HMAC_OUTPUT_USER: | ||||||
|  |         REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_UP); | ||||||
|  |         break; | ||||||
|  |     case HMAC_OUTPUT_DS: | ||||||
|  |         REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE); | ||||||
|  |         break; | ||||||
|  |     case HMAC_OUTPUT_JTAG_ENABLE: | ||||||
|  |         REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG); | ||||||
|  |         break; | ||||||
|  |     case HMAC_OUTPUT_ALL: | ||||||
|  |         REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL); | ||||||
|  |         break; | ||||||
|  |     default: | ||||||
|  |         ; // do nothing, error will be indicated by hmac_hal_config_error() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Selects which hardware key should be used. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_config_hw_key_id(uint32_t key_id) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_SET_PARA_KEY_REG, key_id); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Apply and check configuration. | ||||||
|  |  * | ||||||
|  |  * Afterwards, the configuration can be checked for errors with hmac_hal_config_error(). | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_config_finish(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_SET_PARA_FINISH_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @brief Query HMAC error state after configuration actions. | ||||||
|  |  * | ||||||
|  |  * @return | ||||||
|  |  *  - 1 or greater on error | ||||||
|  |  *  - 0 on success | ||||||
|  |  */ | ||||||
|  | static inline uint32_t hmac_ll_config_error(void) | ||||||
|  | { | ||||||
|  |     return REG_READ(HMAC_QUERY_ERROR_REG); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Wait until the HAL is ready for the next interaction. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_wait_idle(void) | ||||||
|  | { | ||||||
|  |     uint32_t query; | ||||||
|  |     do { | ||||||
|  |         query = REG_READ(HMAC_QUERY_BUSY_REG); | ||||||
|  |     } while(query != 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Write a message block of 512 bits to the HMAC peripheral. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_write_block_512(const uint32_t *block) | ||||||
|  | { | ||||||
|  |     const size_t REG_WIDTH = sizeof(uint32_t); | ||||||
|  |     for (size_t i = 0; i < SHA256_BLOCK_SZ / REG_WIDTH; i++) { | ||||||
|  |         REG_WRITE(HMAC_WR_MESSAGE_MEM + (i * REG_WIDTH), block[i]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     REG_WRITE(HMAC_SET_MESSAGE_ONE_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Read the 256 bit HMAC. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_read_result_256(uint32_t *result) | ||||||
|  | { | ||||||
|  |     const size_t REG_WIDTH = sizeof(uint32_t); | ||||||
|  |     for (size_t i = 0; i < SHA256_DIGEST_SZ / REG_WIDTH; i++) { | ||||||
|  |         result[i] = REG_READ(HMAC_RD_RESULT_MEM + (i * REG_WIDTH)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Clean the HMAC result provided to other hardware. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_clean(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_SET_INVALIDATE_DS_REG, 1); | ||||||
|  |     REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Signals that the following block will be the padded last block. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_msg_padding(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_SET_MESSAGE_PAD_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Signals that all blocks have been written and a padding block will automatically be applied by hardware. | ||||||
|  |  * | ||||||
|  |  * Only applies if the message length is a multiple of 512 bits. | ||||||
|  |  * See the chip TRM HMAC chapter for more details. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_msg_end(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_SET_MESSAGE_END_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief The message including padding fits into one block, so no further action needs to be taken. | ||||||
|  |  * | ||||||
|  |  * This is called after the one-block-message has been written. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_msg_one_block(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_ONE_BLOCK_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Indicate that more blocks will be written after the last block. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_msg_continue(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_SET_MESSAGE_ING_REG, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Clear the HMAC result. | ||||||
|  |  * | ||||||
|  |  * Use this after reading the HMAC result or if aborting after any of the other steps above. | ||||||
|  |  */ | ||||||
|  | static inline void hmac_ll_calc_finish(void) | ||||||
|  | { | ||||||
|  |     REG_WRITE(HMAC_SET_RESULT_FINISH_REG, 2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| /* | /* | ||||||
|  * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD |  * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD | ||||||
|  * |  * | ||||||
|  * SPDX-License-Identifier: Apache-2.0 |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  */ |  */ | ||||||
| @@ -46,6 +46,10 @@ const static char *TAG = "test_ds"; | |||||||
| #include "esp32c5/rom/digital_signature.h" | #include "esp32c5/rom/digital_signature.h" | ||||||
| #include "esp32c5/rom/aes.h" | #include "esp32c5/rom/aes.h" | ||||||
| #include "esp32c5/rom/sha.h" | #include "esp32c5/rom/sha.h" | ||||||
|  | #elif CONFIG_IDF_TARGET_ESP32H21 | ||||||
|  | #include "esp32h21/rom/digital_signature.h" | ||||||
|  | #include "esp32h21/rom/aes.h" | ||||||
|  | #include "esp32h21/rom/sha.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL           (0x1) /*!< HMAC peripheral problem */ | #define ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL           (0x1) /*!< HMAC peripheral problem */ | ||||||
|   | |||||||
| @@ -22,6 +22,8 @@ | |||||||
| #include "esp32p4/rom/digital_signature.h" | #include "esp32p4/rom/digital_signature.h" | ||||||
| #elif CONFIG_IDF_TARGET_ESP32C5 | #elif CONFIG_IDF_TARGET_ESP32C5 | ||||||
| #include "esp32c5/rom/digital_signature.h" | #include "esp32c5/rom/digital_signature.h" | ||||||
|  | #elif CONFIG_IDF_TARGET_ESP32H21 | ||||||
|  | #include "esp32h21/rom/digital_signature.h" | ||||||
| #else | #else | ||||||
| #error   "Selected target does not support esp_rsa_sign_alt (for DS)" | #error   "Selected target does not support esp_rsa_sign_alt (for DS)" | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -47,6 +47,14 @@ config SOC_SHA_SUPPORTED | |||||||
|     bool |     bool | ||||||
|     default y |     default y | ||||||
|  |  | ||||||
|  | config SOC_HMAC_SUPPORTED | ||||||
|  |     bool | ||||||
|  |     default y | ||||||
|  |  | ||||||
|  | config SOC_DIG_SIGN_SUPPORTED | ||||||
|  |     bool | ||||||
|  |     default y | ||||||
|  |  | ||||||
| config SOC_ECC_SUPPORTED | config SOC_ECC_SUPPORTED | ||||||
|     bool |     bool | ||||||
|     default y |     default y | ||||||
|   | |||||||
| @@ -45,8 +45,8 @@ | |||||||
| // #define SOC_SUPPORT_COEXISTENCE         1    //TODO: [ESP32H21] IDF-11658, IDF-11659, IDF-11660 | // #define SOC_SUPPORT_COEXISTENCE         1    //TODO: [ESP32H21] IDF-11658, IDF-11659, IDF-11660 | ||||||
| #define SOC_MPI_SUPPORTED               1 | #define SOC_MPI_SUPPORTED               1 | ||||||
| #define SOC_SHA_SUPPORTED               1 | #define SOC_SHA_SUPPORTED               1 | ||||||
| // #define SOC_HMAC_SUPPORTED              1    //TODO: [ESP32H21] IDF-11495 | #define SOC_HMAC_SUPPORTED              1 | ||||||
| // #define SOC_DIG_SIGN_SUPPORTED          1    //TODO: [ESP32H21] IDF-11497 | #define SOC_DIG_SIGN_SUPPORTED          1 | ||||||
| #define SOC_ECC_SUPPORTED               1 | #define SOC_ECC_SUPPORTED               1 | ||||||
| #define SOC_ECC_EXTENDED_MODES_SUPPORTED   1 | #define SOC_ECC_EXTENDED_MODES_SUPPORTED   1 | ||||||
| // #define SOC_ECDSA_SUPPORTED             1    //TODO: [ESP32H21] IDF-11496 | // #define SOC_ECDSA_SUPPORTED             1    //TODO: [ESP32H21] IDF-11496 | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| | Supported Targets | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | | Supported Targets | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | ||||||
| | ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | | ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | | ||||||
|  |  | ||||||
| # JTAG Re-enable Example | # JTAG Re-enable Example | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| | Supported Targets | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | | Supported Targets | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | | ||||||
| | ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | | ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | | ||||||
|  |  | ||||||
| # NVS Encryption with HMAC-based encryption key protection scheme | # NVS Encryption with HMAC-based encryption key protection scheme | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 nilesh.kale
					nilesh.kale