Merge branch 'feature/hmac_s3' into 'master'

[esp_hw_support]: HMAC upstream support for S3

See merge request espressif/esp-idf!14629
This commit is contained in:
Jakob Hasse 2021-08-13 06:44:49 +00:00
commit 8750034c19
15 changed files with 611 additions and 34 deletions

View File

@ -18,6 +18,20 @@ extern "C" {
* Other unrelated components must not use it.
*/
/**
* @brief Acquire lock for HMAC cryptography peripheral
*
* Internally also takes the SHA & AES lock, as the HMAC depends on the SHA peripheral
*/
void esp_crypto_hmac_lock_acquire(void);
/**
* @brief Release lock for HMAC cryptography peripheral
*
* Internally also releases the SHA & AES lock, as the HMAC depends on the SHA peripheral
*/
void esp_crypto_hmac_lock_release(void);
/**
* @brief Acquire lock for the SHA and AES cryptography peripheral.
*

View File

@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The possible efuse keys for the HMAC peripheral
*/
typedef enum {
HMAC_KEY0 = 0,
HMAC_KEY1,
HMAC_KEY2,
HMAC_KEY3,
HMAC_KEY4,
HMAC_KEY5,
HMAC_KEY_MAX
} hmac_key_id_t;
/**
* @brief
* Calculate the HMAC of a given message.
*
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
* SHA256 is used for the calculation (fixed on ESP32S3).
*
* @note Uses the HMAC peripheral in "upstream" mode.
*
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
* @param message the message for which to calculate the HMAC
* @param message_len message length
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be 32 bytes long
*
* @return
* * ESP_OK, if the calculation was successful,
* * ESP_ERR_INVALID_ARG if message or hmac is a nullptr or if key_id out of range
* * ESP_FAIL, if the hmac calculation failed
*/
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
const void *message,
size_t message_len,
uint8_t *hmac);
#ifdef __cplusplus
}
#endif

View File

@ -15,6 +15,7 @@ set(srcs
if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "../async_memcpy_impl_gdma.c"
"dport_access.c"
"esp_hmac.c"
"esp_crypto_lock.c"
"memprot.c"
"spiram.c")

View File

@ -16,20 +16,34 @@ HMAC: needs SHA
DS: needs HMAC (which needs SHA), AES and MPI
*/
/* Single lock for SHA and AES, sharing a reserved GDMA channel */
static _lock_t s_crypto_sha_aes_lock;
/*
* Single lock for SHA, HMAC, DS and AES peripherals.
* SHA and AES share a reserved GDMA channel.
* DS uses HMAC, HMAC uses SHA, so they may also not be used simulaneously.
*/
static _lock_t s_crypto_sha_aes_hmac_ds_lock;
/* Lock for the MPI/RSA peripheral, also used by the DS peripheral */
static _lock_t s_crypto_mpi_lock;
void esp_crypto_hmac_lock_acquire(void)
{
_lock_acquire_recursive(&s_crypto_sha_aes_hmac_ds_lock);
}
void esp_crypto_hmac_lock_release(void)
{
_lock_release_recursive(&s_crypto_sha_aes_hmac_ds_lock);
}
void esp_crypto_sha_aes_lock_acquire(void)
{
_lock_acquire(&s_crypto_sha_aes_lock);
_lock_acquire_recursive(&s_crypto_sha_aes_hmac_ds_lock);
}
void esp_crypto_sha_aes_lock_release(void)
{
_lock_release(&s_crypto_sha_aes_lock);
_lock_release_recursive(&s_crypto_sha_aes_hmac_ds_lock);
}
void esp_crypto_mpi_lock_acquire(void)

View File

@ -0,0 +1,124 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "driver/periph_ctrl.h"
#include "esp32s3/rom/hmac.h"
#include "esp32s3/rom/ets_sys.h"
#include "esp_hmac.h"
#include "esp_crypto_lock.h"
#include "hal/hmac_hal.h"
#define SHA256_BLOCK_SZ 64
#define SHA256_PAD_SZ 8
/**
* @brief Apply the HMAC padding without the embedded length.
*
* @note This function does not check the data length, it is the responsibility of the other functions in this
* module to make sure that \c data_len is at most SHA256_BLOCK_SZ - 1 so the padding fits in.
* Otherwise, this function has undefined behavior.
* Note however, that for the actual HMAC implementation on ESP32S3, the length also needs to be applied at the end
* of the block. This function alone deosn't do that.
*/
static void write_and_padd(uint8_t *block, const uint8_t *data, uint16_t data_len)
{
memcpy(block, data, data_len);
// Apply a one bit, followed by zero bits (refer to the ESP32S3 TRM).
block[data_len] = 0x80;
bzero(block + data_len + 1, SHA256_BLOCK_SZ - data_len - 1);
}
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
const void *message,
size_t message_len,
uint8_t *hmac)
{
const uint8_t *message_bytes = (const uint8_t *)message;
if (!message || !hmac) {
return ESP_ERR_INVALID_ARG;
}
if (key_id >= HMAC_KEY_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_crypto_hmac_lock_acquire();
// We also enable SHA and DS here. SHA is used by HMAC, DS will otherwise hold SHA in reset state.
periph_module_enable(PERIPH_HMAC_MODULE);
periph_module_enable(PERIPH_SHA_MODULE);
periph_module_enable(PERIPH_DS_MODULE);
hmac_hal_start();
uint32_t conf_error = hmac_hal_configure(HMAC_OUTPUT_USER, key_id);
if (conf_error) {
esp_crypto_hmac_lock_release();
return ESP_FAIL;
}
if (message_len + 1 + SHA256_PAD_SZ <= SHA256_BLOCK_SZ) {
// If message including padding is only one block...
// Last message block, so apply SHA-256 padding rules in software
uint8_t block[SHA256_BLOCK_SZ];
uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
write_and_padd(block, message_bytes, message_len);
// Final block: append the bit length in this block and signal padding to peripheral
memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
&bit_len, sizeof(bit_len));
hmac_hal_write_one_block_512(block);
} else {
// If message including padding is needs more than one block
// write all blocks without padding except the last one
size_t remaining_blocks = message_len / SHA256_BLOCK_SZ;
for (int i = 1; i < remaining_blocks; i++) {
hmac_hal_write_block_512(message_bytes);
message_bytes += SHA256_BLOCK_SZ;
hmac_hal_next_block_normal();
}
// If message fits into one block but without padding, we must not write another block.
if (remaining_blocks) {
hmac_hal_write_block_512(message_bytes);
message_bytes += SHA256_BLOCK_SZ;
}
size_t remaining = message_len % SHA256_BLOCK_SZ;
// Last message block, so apply SHA-256 padding rules in software
uint8_t block[SHA256_BLOCK_SZ];
uint64_t bit_len = __builtin_bswap64(message_len * 8 + 512);
// If the remaining message and appended padding doesn't fit into a single block, we have to write an
// extra block with the rest of the message and potential padding first.
if (remaining >= SHA256_BLOCK_SZ - SHA256_PAD_SZ) {
write_and_padd(block, message_bytes, remaining);
hmac_hal_next_block_normal();
hmac_hal_write_block_512(block);
bzero(block, SHA256_BLOCK_SZ);
} else {
write_and_padd(block, message_bytes, remaining);
}
memcpy(block + SHA256_BLOCK_SZ - sizeof(bit_len),
&bit_len, sizeof(bit_len));
hmac_hal_next_block_padding();
hmac_hal_write_block_512(block);
}
// Read back result (bit swapped)
hmac_hal_read_result_256(hmac);
periph_module_disable(PERIPH_DS_MODULE);
periph_module_disable(PERIPH_SHA_MODULE);
periph_module_disable(PERIPH_HMAC_MODULE);
esp_crypto_hmac_lock_release();
return ESP_OK;
}

View File

@ -14,8 +14,6 @@
#if CONFIG_IDF_ENV_FPGA
#include "esp32s2/rom/efuse.h"
/* Allow testing varying message lengths (truncating the same message)
for various results */
typedef struct {
@ -23,25 +21,29 @@ typedef struct {
uint8_t result[32];
} hmac_result;
static const ets_efuse_block_t key_block = ETS_EFUSE_BLOCK_KEY4;
static const char *TAG = "test_hmac";
static const esp_efuse_block_t key_block = EFUSE_BLK_KEY0;
static void setup_keyblock(void) {
const uint8_t key_data[32] = {
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
25,26,27,28,29,30,31,32
};
int ets_status = ets_efuse_write_key(key_block,
ETS_EFUSE_KEY_PURPOSE_HMAC_UP,
esp_err_t status = esp_efuse_write_key(key_block,
ESP_EFUSE_KEY_PURPOSE_HMAC_UP,
key_data, sizeof(key_data));
if (ets_status == ESP_OK) {
printf("written key!\n");
if (status == ESP_OK) {
printf("Written key!\n");
} else if (ESP_ERR_EFUSE_REPEATED_PROG) {
printf("Key written already.\n");
} else {
printf("writing key failed, maybe written already\n");
printf("ERROR while writing key.\n");
}
}
#if !CONFIG_IDF_TARGET_ESP32S3 // TODO: IDF-3664: S3 JTAG enable hasn't been implemented yet
#include "esp32s2/rom/efuse.h"
static const char *TAG = "test_hmac";
TEST_CASE("HMAC 'downstream' JTAG Enable mode", "[hw_crypto]")
{
int ets_status;
@ -99,6 +101,7 @@ TEST_CASE("HMAC 'downstream' JTAG Disable", "[hw_crypto]")
TEST_ASSERT_EQUAL_HEX32_MESSAGE(ESP_OK, esp_hmac_jtag_disable(),
"JTAG should be disabled now, please manually verify");
}
#endif
TEST_CASE("HMAC 'upstream' MAC generation with zeroes", "[hw_crypto]")
{
@ -1015,6 +1018,12 @@ TEST_CASE("HMAC 'upstream' wait lock", "[hw_crypto]")
}
}
#endif // CONFIG_IDF_ENV_FPGA
/**
* This test is just a parameter test and does not write any keys to efuse.
* It can be done safely on any chip which supports HMAC.
*/
TEST_CASE("HMAC key out of range", "[hw_crypto]")
{
uint8_t hmac[32];
@ -1026,6 +1035,4 @@ TEST_CASE("HMAC key out of range", "[hw_crypto]")
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_hmac_calculate(HMAC_KEY5 + 1, message, 47, hmac));
}
#endif // CONFIG_IDF_ENV_FPGA
#endif // SOC_HMAC_SUPPORTED

View File

@ -82,6 +82,7 @@ if(NOT BOOTLOADER_BUILD)
"touch_sensor_hal.c"
"usb_hal.c"
"esp32s3/brownout_hal.c"
"esp32s3/hmac_hal.c"
"esp32s3/interrupt_descriptor_table.c"
"esp32s3/touch_sensor_hal.c"
"usbh_hal.c")

View File

@ -0,0 +1,74 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/hmac_hal.h"
#include "hal/hmac_ll.h"
void hmac_hal_start(void)
{
hmac_ll_wait_idle();
hmac_ll_start();
}
uint32_t hmac_hal_configure(hmac_hal_output_t config, uint32_t key_id)
{
hmac_ll_wait_idle();
hmac_ll_config_output(config);
hmac_ll_config_hw_key_id(key_id);
hmac_ll_config_finish();
hmac_ll_wait_idle();
uint32_t conf_error = hmac_ll_query_config_error();
if (conf_error) {
hmac_ll_calc_finish();
return 1;
} else if (config != HMAC_OUTPUT_USER) {
// In "downstream" mode, this will be the last hmac operation. Make sure HMAC is ready for
// the other peripheral.
hmac_ll_wait_idle();
}
return 0;
}
void hmac_hal_write_one_block_512(const void *block)
{
hmac_ll_wait_idle();
hmac_ll_write_block_512(block);
hmac_ll_wait_idle();
hmac_ll_msg_one_block();
}
void hmac_hal_write_block_512(const void *block)
{
hmac_ll_wait_idle();
hmac_ll_write_block_512(block);
}
void hmac_hal_next_block_padding(void)
{
hmac_ll_wait_idle();
hmac_ll_msg_padding();
}
void hmac_hal_next_block_normal(void)
{
hmac_ll_wait_idle();
hmac_ll_msg_continue();
}
void hmac_hal_read_result_256(void *result)
{
hmac_ll_wait_idle();
hmac_ll_read_result_256(result);
hmac_ll_calc_finish();
}
void hmac_hal_clean(void)
{
hmac_ll_wait_idle();
hmac_ll_clean();
}

View File

@ -1,16 +1,8 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
@ -99,6 +91,10 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
return SYSTEM_CRYPTO_SHA_CLK_EN;
case PERIPH_RSA_MODULE:
return SYSTEM_CRYPTO_RSA_CLK_EN;
case PERIPH_HMAC_MODULE:
return SYSTEM_CRYPTO_HMAC_CLK_EN;
case PERIPH_DS_MODULE:
return SYSTEM_CRYPTO_DS_CLK_EN;
default:
return 0;
}
@ -106,9 +102,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool enable)
{
(void)enable; // unused
switch (periph) {
case PERIPH_RMT_MODULE:
return SYSTEM_RMT_RST;
@ -162,6 +155,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
return SYSTEM_RST_EN_DEDICATED_GPIO;
case PERIPH_GDMA_MODULE:
return SYSTEM_DMA_RST;
case PERIPH_HMAC_MODULE:
return SYSTEM_CRYPTO_HMAC_RST;
case PERIPH_AES_MODULE:
if (enable == true) {
// Clear reset on digital signature, otherwise AES unit is held in reset also.
@ -207,6 +202,7 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
case PERIPH_SDMMC_MODULE:
case PERIPH_LCD_CAM_MODULE:
case PERIPH_GDMA_MODULE:
case PERIPH_HMAC_MODULE:
case PERIPH_AES_MODULE:
case PERIPH_SHA_MODULE:
case PERIPH_RSA_MODULE:
@ -230,8 +226,9 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
return SYSTEM_CORE_RST_EN_REG;
case PERIPH_UART2_MODULE:
case PERIPH_SDMMC_MODULE:
case PERIPH_GDMA_MODULE:
case PERIPH_LCD_CAM_MODULE:
case PERIPH_GDMA_MODULE:
case PERIPH_HMAC_MODULE:
case PERIPH_AES_MODULE:
case PERIPH_SHA_MODULE:
case PERIPH_RSA_MODULE:

View File

@ -0,0 +1,101 @@
/*
* SPDX-FileCopyrightText: 2015-2021 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 <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* 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.
*/
typedef enum {
HMAC_OUTPUT_USER = 0, /**< Let user provide a message and read the HMAC result */
HMAC_OUTPUT_DS = 1, /**< HMAC is provided to the DS peripheral to decrypt DS private key parameters */
HMAC_OUTPUT_JTAG_ENABLE = 2, /**< HMAC is used to enable JTAG after soft-disabling it */
HMAC_OUTPUT_ALL = 3 /**< HMAC is used for both as DS input for or enabling JTAG */
} hmac_hal_output_t;
/**
* @brief Make the peripheral ready for use.
*
* This triggers any further steps necessary after enabling the device
*/
void hmac_hal_start(void);
/**
* @brief Configure which hardware key slot should be used and configure the target of the HMAC output.
*
* @note Writing out-of-range values is undefined behavior. The user has to ensure that the parameters are in range.
*
* @param config The target of the HMAC. Possible targets are described in \c hmac_hal_output_t.
* See the ESP32S3 TRM for more details.
* @param key_id The ID of the hardware key slot to be used.
*
* @return 0 if the configuration was successful, non-zero if not.
* An unsuccessful configuration means that the purpose value in the eFuse of the corresponding key slot
* doesn't match to supplied value of \c config.
*/
uint32_t hmac_hal_configure(hmac_hal_output_t config, uint32_t key_id);
/**
* @brief Write a padded single-block message of 512 bits to the HMAC peripheral.
*
* The message must not be longer than one block (512 bits) and the padding has to be applied by software before
* writing. The padding has to be able to fit into the block after the message.
* For more information on HMAC padding, see the ESP32S3 TRM.
*/
void hmac_hal_write_one_block_512(const void *block);
/**
* @brief Write a message block of 512 bits to the HMAC peripheral.
*
* This function must be used incombination with \c hmac_hal_next_block_normal() or \c hmac_hal_next_block_padding().
* The first message block is written without any prerequisite.
* All message blocks which are not the last one, need a call to \c hmac_hal_next_block_normal() before, indicating
* to the hardware that a "normal", i.e. non-padded block will follow. This is even the case for a block which begins
* padding already but where the padding doesn't fit in (remaining message size > (block size - padding size)).
* Before writing the last block which contains the padding, a call to \c hmac_hal_next_block_padding() is necessary
* to indicate to the hardware that a block with padding will be written.
*
* For more information on HMAC padding, see the ESP32S3 TRM.
*/
void hmac_hal_write_block_512(const void *block);
/**
* @brief Indicate to the hardware that a normal block will be written.
*/
void hmac_hal_next_block_normal(void);
/**
* @brief Indicate to the hardware that a block with padding will be written.
*/
void hmac_hal_next_block_padding(void);
/**
* @brief Read the 256 bit HMAC result from the hardware.
*/
void hmac_hal_read_result_256(void *result);
/**
* @brief Clear (invalidate) the HMAC result provided to other hardware.
*/
void hmac_hal_clean(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,187 @@
/*
* SPDX-FileCopyrightText: 2015-2021 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 "soc/hwcrypto_reg.h"
#define SHA256_BLOCK_SZ 64
#define SHA256_DIGEST_SZ 32
#define HMAC_LL_EFUSE_KEY_PURPOSE_DOWN_JTAG 6
#define HMAC_LL_EFUSE_KEY_PURPOSE_DOWN_DIGITAL_SIGNATURE 7
#define HMAC_LL_EFUSE_KEY_PURPOSE_UP 8
#define HMAC_LL_EFUSE_KEY_PURPOSE_DOWN_ALL 5
#ifdef __cplusplus
extern "C" {
#endif
/**
* 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, HMAC_LL_EFUSE_KEY_PURPOSE_UP);
break;
case HMAC_OUTPUT_DS:
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, HMAC_LL_EFUSE_KEY_PURPOSE_DOWN_DIGITAL_SIGNATURE);
break;
case HMAC_OUTPUT_JTAG_ENABLE:
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, HMAC_LL_EFUSE_KEY_PURPOSE_DOWN_JTAG);
break;
case HMAC_OUTPUT_ALL:
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, HMAC_LL_EFUSE_KEY_PURPOSE_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_query_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_WDATA_BASE + (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_RDATA_BASE + (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 ESP32S3 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

View File

@ -52,6 +52,8 @@ typedef enum {
PERIPH_BT_LC_MODULE,
PERIPH_AES_MODULE,
PERIPH_SHA_MODULE,
PERIPH_HMAC_MODULE,
PERIPH_DS_MODULE,
PERIPH_RSA_MODULE,
PERIPH_SYSTIMER_MODULE,
PERIPH_GDMA_MODULE,

View File

@ -19,7 +19,7 @@
#define SOC_RTC_SLOW_MEM_SUPPORTED 1
#define SOC_CCOMP_TIMER_SUPPORTED 1
#define SOC_DIG_SIGN_SUPPORTED 0
#define SOC_HMAC_SUPPORTED 0
#define SOC_HMAC_SUPPORTED 1
#define SOC_ASYNC_MEMCPY_SUPPORTED 1
#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
#define SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS 1

View File

@ -194,7 +194,6 @@ ESP32_DOCS = ['api-guides/ulp_instruction_set.rst',
ESP32S2_DOCS = ['hw-reference/esp32s2/**',
'api-guides/ulps2_instruction_set.rst',
'api-guides/usb-console.rst',
'api-reference/peripherals/hmac.rst',
'api-reference/peripherals/ds.rst',
'api-reference/peripherals/spi_slave_hd.rst',
'api-reference/peripherals/temp_sensor.rst',

View File

@ -1,5 +1,6 @@
INPUT += \
$(IDF_PATH)/components/ulp/include/$(IDF_TARGET)/ulp.h \
$(IDF_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_hmac.h \
$(IDF_PATH)/components/hal/include/hal/mcpwm_types.h \
$(IDF_PATH)/components/driver/include/driver/mcpwm.h \
$(IDF_PATH)/components/hal/include/hal/pcnt_types.h \