From 8203d40fc35fdfbd88732b302db065cd98a92904 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Mon, 30 Jan 2023 09:39:28 +0530 Subject: [PATCH] esp32h2: add support for SHA peripheral Closes IDF-6275 --- .../include/soc/esp32h2/esp_crypto_lock.h | 2 +- .../port/esp32h2/CMakeLists.txt | 4 + .../port/esp32h2/esp_crypto_lock.c | 75 +++++++++ components/hal/esp32h2/include/hal/sha_ll.h | 149 ++++++++++++++++++ .../esp32h2/include/soc/Kconfig.soc_caps.in | 8 + components/soc/esp32h2/include/soc/soc_caps.h | 6 +- 6 files changed, 239 insertions(+), 5 deletions(-) create mode 100644 components/esp_hw_support/port/esp32h2/esp_crypto_lock.c create mode 100644 components/hal/esp32h2/include/hal/sha_ll.h diff --git a/components/esp_hw_support/include/soc/esp32h2/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp32h2/esp_crypto_lock.h index 870025ffde..c768bd7377 100644 --- a/components/esp_hw_support/include/soc/esp32h2/esp_crypto_lock.h +++ b/components/esp_hw_support/include/soc/esp32h2/esp_crypto_lock.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_hw_support/port/esp32h2/CMakeLists.txt b/components/esp_hw_support/port/esp32h2/CMakeLists.txt index 9fbf4d7ad4..701cdd82ea 100644 --- a/components/esp_hw_support/port/esp32h2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32h2/CMakeLists.txt @@ -7,6 +7,10 @@ set(srcs "rtc_clk_init.c" "chip_info.c" ) +if(NOT BOOTLOADER_BUILD) + list(APPEND srcs "esp_crypto_lock.c") +endif() + add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") diff --git a/components/esp_hw_support/port/esp32h2/esp_crypto_lock.c b/components/esp_hw_support/port/esp32h2/esp_crypto_lock.c new file mode 100644 index 0000000000..3936a75b76 --- /dev/null +++ b/components/esp_hw_support/port/esp32h2/esp_crypto_lock.c @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "esp_crypto_lock.h" + +/* Lock overview: +SHA: peripheral independent, but DMA is shared with AES +AES: peripheral independent, but DMA is shared with SHA +MPI/RSA: independent +HMAC: needs SHA +DS: needs HMAC (which needs SHA), AES and MPI +*/ + +/* Lock for DS peripheral */ +static _lock_t s_crypto_ds_lock; + +/* Lock for HMAC peripheral */ +static _lock_t s_crypto_hmac_lock; + +/* Lock for the MPI/RSA peripheral, also used by the DS peripheral */ +static _lock_t s_crypto_mpi_lock; + +/* Single lock for SHA and AES, sharing a reserved GDMA channel */ +static _lock_t s_crypto_sha_aes_lock; + +void esp_crypto_hmac_lock_acquire(void) +{ + _lock_acquire(&s_crypto_hmac_lock); + esp_crypto_sha_aes_lock_acquire(); +} + +void esp_crypto_hmac_lock_release(void) +{ + esp_crypto_sha_aes_lock_release(); + _lock_release(&s_crypto_hmac_lock); +} + +void esp_crypto_ds_lock_acquire(void) +{ + _lock_acquire(&s_crypto_ds_lock); + esp_crypto_hmac_lock_acquire(); + esp_crypto_mpi_lock_acquire(); +} + +void esp_crypto_ds_lock_release(void) +{ + esp_crypto_mpi_lock_release(); + esp_crypto_hmac_lock_release(); + _lock_release(&s_crypto_ds_lock); +} + +void esp_crypto_sha_aes_lock_acquire(void) +{ + _lock_acquire(&s_crypto_sha_aes_lock); +} + +void esp_crypto_sha_aes_lock_release(void) +{ + _lock_release(&s_crypto_sha_aes_lock); +} + +void esp_crypto_mpi_lock_acquire(void) +{ + _lock_acquire(&s_crypto_mpi_lock); +} + +void esp_crypto_mpi_lock_release(void) +{ + _lock_release(&s_crypto_mpi_lock); +} diff --git a/components/hal/esp32h2/include/hal/sha_ll.h b/components/hal/esp32h2/include/hal/sha_ll.h new file mode 100644 index 0000000000..063159232c --- /dev/null +++ b/components/hal/esp32h2/include/hal/sha_ll.h @@ -0,0 +1,149 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "soc/hwcrypto_reg.h" +#include "hal/sha_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Start a new SHA block conversions (no initial hash in HW) + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_start_block(esp_sha_type sha_type) +{ + REG_WRITE(SHA_MODE_REG, sha_type); + REG_WRITE(SHA_START_REG, 1); +} + +/** + * @brief Continue a SHA block conversion (initial hash in HW) + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_continue_block(esp_sha_type sha_type) +{ + REG_WRITE(SHA_MODE_REG, sha_type); + REG_WRITE(SHA_CONTINUE_REG, 1); +} + +/** + * @brief Start a new SHA message conversion using DMA (no initial hash in HW) + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_start_dma(esp_sha_type sha_type) +{ + REG_WRITE(SHA_MODE_REG, sha_type); + REG_WRITE(SHA_DMA_START_REG, 1); +} + +/** + * @brief Continue a SHA message conversion using DMA (initial hash in HW) + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_continue_dma(esp_sha_type sha_type) +{ + REG_WRITE(SHA_MODE_REG, sha_type); + REG_WRITE(SHA_DMA_CONTINUE_REG, 1); +} + +/** + * @brief Load the current hash digest to digest register + * + * @note Happens automatically on ESP32H2 + * + * @param sha_type The SHA algorithm type + */ +static inline void sha_ll_load(esp_sha_type sha_type) +{ +} + +/** + * @brief Sets the number of message blocks to be hashed + * + * @note DMA operation only + * + * @param num_blocks Number of message blocks to process + */ +static inline void sha_ll_set_block_num(size_t num_blocks) +{ + REG_WRITE(SHA_DMA_BLOCK_NUM_REG, num_blocks); +} + +/** + * @brief Checks if the SHA engine is currently busy hashing a block + * + * @return true SHA engine busy + * @return false SHA engine idle + */ +static inline bool sha_ll_busy(void) +{ + return REG_READ(SHA_BUSY_REG); +} + +/** + * @brief Write a text (message) block to the SHA engine + * + * @param input_text Input buffer to be written to the SHA engine + * @param block_word_len Number of words in block + */ +static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len) +{ + uint32_t *data_words = (uint32_t *)input_text; + uint32_t *reg_addr_buf = (uint32_t *)(SHA_M_MEM_REG); + + for (int i = 0; i < block_word_len; i++) { + REG_WRITE(®_addr_buf[i], data_words[i]); + } +} + +/** + * @brief Read the message digest from the SHA engine + * + * @param sha_type The SHA algorithm type + * @param digest_state Buffer that message digest will be written to + * @param digest_word_len Length of the message digest + */ +static inline void sha_ll_read_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len) +{ + uint32_t *digest_state_words = (uint32_t *)digest_state; + const size_t REG_WIDTH = sizeof(uint32_t); + + for (size_t i = 0; i < digest_word_len; i++) { + digest_state_words[i] = REG_READ(SHA_H_MEM_REG + (i * REG_WIDTH)); + } + +} + +/** + * @brief Write the message digest to the SHA engine + * + * @param sha_type The SHA algorithm type + * @param digest_state Message digest to be written to SHA engine + * @param digest_word_len Length of the message digest + */ +static inline void sha_ll_write_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len) +{ + uint32_t *digest_state_words = (uint32_t *)digest_state; + uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_MEM_REG); + + for (int i = 0; i < digest_word_len; i++) { + REG_WRITE(®_addr_buf[i], digest_state_words[i]); + } +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index ea0fff2c5b..ba84668377 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -55,6 +55,14 @@ config SOC_SYSTIMER_SUPPORTED bool default y +config SOC_AES_SUPPORTED + bool + default y + +config SOC_SHA_SUPPORTED + bool + default y + config SOC_BOD_SUPPORTED bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 3826a37869..93ae71929f 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -50,9 +50,9 @@ // #define SOC_GPSPI_SUPPORTED 1 // TODO: IDF-6264 #define SOC_SYSTIMER_SUPPORTED 1 // #define SOC_SUPPORT_COEXISTENCE 1 // TODO: IDF-6416 -// #define SOC_AES_SUPPORTED 1 // TODO: IDF-6280 +#define SOC_AES_SUPPORTED 1 // #define SOC_MPI_SUPPORTED 1 // TODO: IDF-6415 -// #define SOC_SHA_SUPPORTED 1 // TODO: IDF-6275 +#define SOC_SHA_SUPPORTED 1 // #define SOC_HMAC_SUPPORTED 1 // TODO: IDF-6279 // #define SOC_DIG_SIGN_SUPPORTED 1 // TODO: IDF-6285 // #define SOC_FLASH_ENC_SUPPORTED 1 // TODO: IDF-6282 @@ -63,7 +63,6 @@ /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_32M 1 -// TODO: IDF-6280 (Copy from esp32c6, need check) /*-------------------------- AES CAPS -----------------------------------------*/ #define SOC_AES_SUPPORT_DMA (1) @@ -272,7 +271,6 @@ /*--------------------------- RSA CAPS ---------------------------------------*/ #define SOC_RSA_MAX_BIT_LEN (3072) -// TODO: IDF-6275 (Copy from esp32c6, need check) /*--------------------------- SHA CAPS ---------------------------------------*/ /* Max amount of bytes in a single DMA operation is 4095,