mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-03 22:08:28 +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