Explorar el Código

esp32h2: add support for SHA peripheral

Closes IDF-6275
Mahavir Jain hace 3 años
padre
commit
8203d40fc3

+ 1 - 1
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
  */

+ 4 - 0
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}")

+ 75 - 0
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 <sys/lock.h>
+
+#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);
+}

+ 149 - 0
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 <stdbool.h>
+#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(&reg_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(&reg_addr_buf[i], digest_state_words[i]);
+    }
+}
+
+
+#ifdef __cplusplus
+}
+#endif

+ 8 - 0
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

+ 2 - 4
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,