Răsfoiți Sursa

Merge branch 'feature/sha_hal' into 'master'

SHA: add HAL layer and refactor

See merge request espressif/esp-idf!10065
Angus Gratton 5 ani în urmă
părinte
comite
ff4d82c7d2
42 a modificat fișierele cu 1695 adăugiri și 2109 ștergeri
  1. 1 1
      components/esp32/test/test_aes_sha_rsa.c
  2. 1 1
      components/esp32/test/test_sha.c
  3. 1 1
      components/esp32s2/test/test_sha.c
  4. 1 0
      components/esp32s3/CMakeLists.txt
  5. 56 0
      components/esp32s3/esp_crypto_lock.c
  6. 61 0
      components/esp32s3/include/esp_crypto_lock.h
  7. 2 1
      components/esp_rom/include/esp32/rom/sha.h
  8. 1 0
      components/hal/CMakeLists.txt
  9. 156 0
      components/hal/esp32/include/hal/sha_ll.h
  10. 81 0
      components/hal/esp32s2/include/hal/crypto_dma_ll.h
  11. 173 0
      components/hal/esp32s2/include/hal/sha_ll.h
  12. 1 0
      components/hal/esp32s3/include/hal/clk_gate_ll.h
  13. 173 0
      components/hal/esp32s3/include/hal/sha_ll.h
  14. 38 0
      components/hal/include/hal/sha_types.h
  15. 199 0
      components/hal/sha_hal.c
  16. 12 5
      components/mbedtls/CMakeLists.txt
  17. 6 2
      components/mbedtls/component.mk
  18. 0 255
      components/mbedtls/port/esp32s2/esp_sha1.c
  19. 0 267
      components/mbedtls/port/esp32s2/esp_sha256.c
  20. 0 317
      components/mbedtls/port/esp32s3/esp_sha512.c
  21. 0 384
      components/mbedtls/port/esp32s3/sha.c
  22. 4 195
      components/mbedtls/port/include/esp32/sha.h
  23. 3 150
      components/mbedtls/port/include/esp32s2/sha.h
  24. 3 7
      components/mbedtls/port/include/sha/sha_dma.h
  25. 207 0
      components/mbedtls/port/include/sha/sha_parallel_engine.h
  26. 13 36
      components/mbedtls/port/include/sha1_alt.h
  27. 16 45
      components/mbedtls/port/include/sha256_alt.h
  28. 13 49
      components/mbedtls/port/include/sha512_alt.h
  29. 7 6
      components/mbedtls/port/sha/dma/esp_sha1.c
  30. 6 5
      components/mbedtls/port/sha/dma/esp_sha256.c
  31. 6 5
      components/mbedtls/port/sha/dma/esp_sha512.c
  32. 60 147
      components/mbedtls/port/sha/dma/sha.c
  33. 30 15
      components/mbedtls/port/sha/esp_sha.c
  34. 20 15
      components/mbedtls/port/sha/parallel_engine/esp_sha1.c
  35. 54 51
      components/mbedtls/port/sha/parallel_engine/esp_sha256.c
  36. 31 35
      components/mbedtls/port/sha/parallel_engine/esp_sha512.c
  37. 24 113
      components/mbedtls/port/sha/parallel_engine/sha.c
  38. 91 0
      components/soc/include/hal/sha_hal.h
  39. 34 0
      components/soc/soc/esp32/include/soc/sha_caps.h
  40. 54 0
      components/soc/soc/esp32s2/include/soc/sha_caps.h
  41. 54 0
      components/soc/soc/esp32s3/include/soc/sha_caps.h
  42. 2 1
      components/soc/soc/esp32s3/include/soc/soc_caps.h

+ 1 - 1
components/esp32/test/test_aes_sha_rsa.c

@@ -16,7 +16,7 @@
 #include "soc/rtc.h"
 #include "esp_log.h"
 #include "mbedtls/sha256.h"
-#include "esp32/sha.h"
+#include "sha/sha_parallel_engine.h"
 #include "esp32/aes.h"
 #include "mbedtls/rsa.h"
 

+ 1 - 1
components/esp32/test/test_sha.c

@@ -13,7 +13,7 @@
 #include "mbedtls/sha1.h"
 #include "mbedtls/sha256.h"
 #include "mbedtls/sha512.h"
-#include "esp32/sha.h"
+#include "sha/sha_parallel_engine.h"
 #include "ccomp_timer.h"
 
 /* Note: Most of the SHA functions are called as part of mbedTLS, so

+ 1 - 1
components/esp32s2/test/test_sha.c

@@ -13,7 +13,7 @@
 #include "mbedtls/sha1.h"
 #include "mbedtls/sha256.h"
 #include "mbedtls/sha512.h"
-#include "esp32s2/sha.h"
+#include "sha/sha_dma.h"
 
 /* Note: Most of the SHA functions are called as part of mbedTLS, so
 are tested as part of mbedTLS tests. Only esp_sha() is different.

+ 1 - 0
components/esp32s3/CMakeLists.txt

@@ -16,6 +16,7 @@ else()
              "clk.c"
              "crosscore_int.c"
              "dport_access.c"
+             "esp_crypto_lock.c"
              "hw_random.c"
             
              "memprot.c"

+ 56 - 0
components/esp32s3/esp_crypto_lock.c

@@ -0,0 +1,56 @@
+// 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.
+
+#include <sys/lock.h>
+
+#include "esp_crypto_lock.h"
+
+/* Lock for the SHA peripheral, also used by the HMAC and DS peripheral */
+static _lock_t s_crypto_sha_lock;
+
+/* Lock for the AES peripheral, also used by DS peripheral */
+static _lock_t s_crypto_aes_lock;
+
+/* Lock for the MPI/RSA peripheral, also used by the DS peripheral */
+static _lock_t s_crypto_mpi_lock;
+
+void esp_crypto_sha_lock_acquire(void)
+{
+    _lock_acquire(&s_crypto_sha_lock);
+}
+
+void esp_crypto_sha_lock_release(void)
+{
+    _lock_release(&s_crypto_sha_lock);
+}
+
+void esp_crypto_aes_lock_acquire(void)
+{
+    _lock_acquire(&s_crypto_aes_lock);
+}
+
+void esp_crypto_aes_lock_release(void)
+{
+    _lock_release(&s_crypto_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);
+}

+ 61 - 0
components/esp32s3/include/esp_crypto_lock.h

@@ -0,0 +1,61 @@
+// 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.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This API should be used by all components which use the SHA, AES, HMAC and DS crypto hardware on the ESP32S3.
+ * Not all of them can be used in parallel because they use the same underlying module.
+ * E.g., HMAC uses SHA or DS uses HMAC and AES. See the ESP32S3 Technical Reference Manual for more details.
+ *
+ * Other unrelated components must not use it.
+ */
+
+/**
+ * Acquire lock for the SHA cryptography peripheral
+ */
+void esp_crypto_sha_lock_acquire(void);
+
+/**
+ * Release lock for the SHA cryptography peripheral
+ */
+void esp_crypto_sha_lock_release(void);
+
+/**
+ * Acquire lock for the AES cryptography peripheral
+ */
+void esp_crypto_aes_lock_acquire(void);
+
+/**
+ * Release lock for the AES cryptography peripheral
+ */
+void esp_crypto_aes_lock_release(void);
+
+/**
+ * Acquire lock for the MPI/RSA cryptography peripheral
+ */
+void esp_crypto_mpi_lock_acquire(void);
+
+/**
+ * Release lock for the MPI/RSA cryptography peripheral
+ */
+void esp_crypto_mpi_lock_release(void);
+
+#ifdef __cplusplus
+}
+#endif

+ 2 - 1
components/esp_rom/include/esp32/rom/sha.h

@@ -24,6 +24,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <stddef.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -44,7 +45,7 @@ enum SHA_TYPE {
     SHA_INVALID = -1,
 };
 
-/* Do not use these function in multi core mode due to 
+/* Do not use these function in multi core mode due to
  * inside they have no safe implementation (without DPORT workaround).
 */
 void ets_sha_init(SHA_CTX *ctx);

+ 1 - 0
components/hal/CMakeLists.txt

@@ -32,6 +32,7 @@ if(NOT BOOTLOADER_BUILD)
                 "soc_hal.c"
                 "twai_hal.c"
                 "interrupt_controller_hal.c"
+		 "sha_hal.c"
                 "${target}/interrupt_descriptor_table.c")
 
     if(${target} STREQUAL "esp32")

+ 156 - 0
components/hal/esp32/include/hal/sha_ll.h

@@ -0,0 +1,156 @@
+// Copyright 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.
+#pragma once
+
+#include <stdbool.h>
+#include "hal/sha_types.h"
+#include "soc/hwcrypto_reg.h"
+#include "soc/dport_access.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SHA_LL_TYPE_OFFSET 0x10
+
+/**
+ * @brief Returns the LOAD_REG register address for the given sha type
+ *
+ * @param sha_type The SHA algorithm type
+ * @return uint32_t the LOAD_REG register address
+ */
+inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type)
+{
+    return SHA_1_LOAD_REG + sha_type * SHA_LL_TYPE_OFFSET;
+}
+
+/**
+ * @brief Returns the BUSY register address for the given sha type
+ *
+ * @param sha_type The SHA algorithm type
+ * @return uint32_t the BUSY register address
+ */
+inline static uint32_t SHA_BUSY_REG(esp_sha_type sha_type)
+{
+    return SHA_1_BUSY_REG + sha_type * SHA_LL_TYPE_OFFSET;
+}
+
+/**
+ * @brief Returns the START register address for the given sha type
+ *
+ * @param sha_type The SHA algorithm type
+ * @return uint32_t the START register address
+ */
+inline static uint32_t SHA_START_REG(esp_sha_type sha_type)
+{
+    return SHA_1_START_REG + sha_type * SHA_LL_TYPE_OFFSET;
+}
+
+/**
+ * @brief Returns the CONTINUE register address for the given sha type
+ *
+ * @param sha_type The SHA algorithm type
+ * @return uint32_t the CONTINUE register address
+ */
+inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type)
+{
+    return SHA_1_CONTINUE_REG + sha_type * SHA_LL_TYPE_OFFSET;
+}
+
+/**
+ * @brief Start a new SHA block conversion (no initial hash in HW)
+ *
+ * @param sha_type The SHA algorithm type
+ */
+static inline void sha_ll_start_block(esp_sha_type sha_type)
+{
+    DPORT_REG_WRITE(SHA_START_REG(sha_type), 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)
+{
+    DPORT_REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
+}
+
+/**
+ * @brief Load the current hash digest to digest register
+ *
+ * @param sha_type The SHA algorithm type
+ */
+static inline void sha_ll_load(esp_sha_type sha_type)
+{
+    DPORT_REG_WRITE(SHA_LOAD_REG(sha_type), 1);
+}
+
+/**
+ * @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 (DPORT_REG_READ(SHA_1_BUSY_REG) || DPORT_REG_READ(SHA_256_BUSY_REG)
+            || DPORT_REG_READ(SHA_384_BUSY_REG) || DPORT_REG_READ(SHA_512_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 *reg_addr_buf = NULL;
+    uint32_t *data_words = NULL;
+    reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
+    data_words = (uint32_t *)input_text;
+    for (int i = 0; i < block_word_len; i++) {
+        reg_addr_buf[i] = __builtin_bswap32(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;
+    uint32_t *reg_addr_buf  = (uint32_t *)(SHA_TEXT_BASE);
+    if (sha_type == SHA2_384 || sha_type == SHA2_512) {
+        /* for these ciphers using 64-bit states, swap each pair of words */
+        DPORT_INTERRUPT_DISABLE(); // Disable interrupt only on current CPU.
+        for (int i = 0; i < digest_word_len; i += 2) {
+            digest_state_words[i + 1] = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i]);
+            digest_state_words[i]   = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i + 1]);
+        }
+        DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level
+    } else {
+        esp_dport_access_read_buffer(digest_state_words, (uint32_t)&reg_addr_buf[0], digest_word_len);
+    }
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 81 - 0
components/hal/esp32s2/include/hal/crypto_dma_ll.h

@@ -0,0 +1,81 @@
+// Copyright 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.
+
+/*******************************************************************************
+ * NOTICE
+ * The ll is not public api, don't use in application code.
+ * See readme.md in soc/include/hal/readme.md
+ ******************************************************************************/
+#pragma once
+
+#include "soc/hwcrypto_reg.h"
+#include "soc/dport_reg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    CRYPTO_DMA_AES = 0,
+    CRYPTO_DMA_SHA,
+} crypto_dma_mode_t;
+
+/**
+ * @brief Resets set the outlink
+ *
+ */
+static inline void crypto_dma_ll_outlink_reset(void)
+{
+    SET_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
+    CLEAR_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
+}
+
+
+/**
+ * @brief Selects the crypto DMA mode
+ *
+ * @param mode Mode to use, AES or SHA
+ */
+static inline void crypto_dma_ll_set_mode(crypto_dma_mode_t mode)
+{
+    REG_WRITE(CRYPTO_DMA_AES_SHA_SELECT_REG, mode);
+}
+
+/**
+ * @brief Sets up the outlink for a transfer
+ *
+ * @param outlink_addr Address of the outlink buffer
+ */
+static inline void crypto_dma_ll_outlink_set(uint32_t outlink_addr)
+{
+    CLEAR_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_ADDR);
+    SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, outlink_addr & OUT_LINK_REG_OUTLINK_ADDR);
+}
+
+/**
+ * @brief Starts the outlink
+ *
+ */
+static inline void crypto_dma_ll_outlink_start(void)
+{
+    SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_START);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+

+ 173 - 0
components/hal/esp32s2/include/hal/sha_ll.h

@@ -0,0 +1,173 @@
+// Copyright 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.
+#pragma once
+
+#include <stdbool.h>
+#include "soc/hwcrypto_reg.h"
+#include "hal/sha_types.h"
+#include "soc/dport_reg.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 ESP32S2
+ *
+ * @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_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_TEXT_BASE);
+
+    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;
+
+    esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, digest_word_len);
+}
+
+/**
+ * @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_BASE);
+
+    for (int i = 0; i < digest_word_len; i++) {
+        REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
+    }
+}
+
+/**
+ * @brief Sets SHA512_t T_string parameter
+ *
+ * @param t_string T_string parameter
+ */
+static inline void sha_ll_t_string_set(uint32_t t_string)
+{
+    REG_WRITE(SHA_T_STRING_REG, t_string);
+}
+
+/**
+ * @brief Sets SHA512_t T_string parameter's length
+ *
+ * @param t_len T_string parameter length
+ */
+static inline void sha_ll_t_len_set(uint8_t t_len)
+{
+    REG_WRITE(SHA_T_LENGTH_REG, t_len);
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 1 - 0
components/hal/esp32s3/include/hal/clk_gate_ll.h

@@ -230,6 +230,7 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
     case PERIPH_SDMMC_MODULE:
     case PERIPH_GDMA_MODULE:
     case PERIPH_AES_MODULE:
+    case PERIPH_SHA_MODULE:
     case PERIPH_RSA_MODULE:
         return SYSTEM_PERIP_RST_EN1_REG;
     default:

+ 173 - 0
components/hal/esp32s3/include/hal/sha_ll.h

@@ -0,0 +1,173 @@
+// Copyright 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.
+#pragma once
+
+#include <stdbool.h>
+#include "soc/hwcrypto_reg.h"
+#include "hal/sha_types.h"
+#include "soc/dport_reg.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 ESP32S3
+ *
+ * @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_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_TEXT_BASE);
+
+    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;
+
+    esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, digest_word_len);
+}
+
+/**
+ * @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_BASE);
+
+    for (int i = 0; i < digest_word_len; i++) {
+        REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
+    }
+}
+
+/**
+ * @brief Sets SHA512_t T_string parameter
+ *
+ * @param t_string T_string parameter
+ */
+static inline void sha_ll_t_string_set(uint32_t t_string)
+{
+    REG_WRITE(SHA_T_STRING_REG, t_string);
+}
+
+/**
+ * @brief Sets SHA512_t T_string parameter's length
+ *
+ * @param t_len T_string parameter length
+ */
+static inline void sha_ll_t_len_set(uint8_t t_len)
+{
+    REG_WRITE(SHA_T_LENGTH_REG, t_len);
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 38 - 0
components/hal/include/hal/sha_types.h

@@ -0,0 +1,38 @@
+// Copyright 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.
+
+#pragma once
+
+#include "sdkconfig.h"
+
+/* Use enum from rom for backwards compatibility */
+#if CONFIG_IDF_TARGET_ESP32
+#include "esp32/rom/sha.h"
+typedef enum SHA_TYPE esp_sha_type;
+#elif CONFIG_IDF_TARGET_ESP32S2
+#include "esp32s2/rom/sha.h"
+typedef SHA_TYPE esp_sha_type;
+#elif CONFIG_IDF_TARGET_ESP32S3
+#include "esp32s3/rom/sha.h"
+typedef SHA_TYPE esp_sha_type;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif

+ 199 - 0
components/hal/sha_hal.c

@@ -0,0 +1,199 @@
+// Copyright 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.
+
+// The HAL layer for SHA
+
+#include "hal/sha_hal.h"
+#include "hal/sha_types.h"
+#include "hal/sha_ll.h"
+#include "soc/soc_caps.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#if SOC_SHA_CRYPTO_DMA
+#include "soc/crypto_dma_reg.h"
+#include "hal/crypto_dma_ll.h"
+#elif SOC_SHA_GENERAL_DMA
+#include "hal/gdma_ll.h"
+#define DMA_PERIPH_SHA 7
+#endif
+
+#define SHA1_STATE_LEN_WORDS    (160 / 32)
+#define SHA256_STATE_LEN_WORDS  (256 / 32)
+#define SHA512_STATE_LEN_WORDS  (512 / 32)
+
+#if CONFIG_IDF_TARGET_ESP32
+
+/* Return state size (in words) for a given SHA type */
+inline static size_t state_length(esp_sha_type type)
+{
+    switch (type) {
+    case SHA1:
+        return SHA1_STATE_LEN_WORDS;
+    case SHA2_256:
+        return SHA256_STATE_LEN_WORDS;
+    case SHA2_384:
+    case SHA2_512:
+        return SHA512_STATE_LEN_WORDS;
+    default:
+        return 0;
+    }
+}
+
+#else
+/* Return state size (in words) for a given SHA type */
+inline static size_t state_length(esp_sha_type type)
+{
+    switch (type) {
+    case SHA1:
+        return SHA1_STATE_LEN_WORDS;
+    case SHA2_224:
+    case SHA2_256:
+        return SHA256_STATE_LEN_WORDS;
+    case SHA2_384:
+    case SHA2_512:
+    case SHA2_512224:
+    case SHA2_512256:
+    case SHA2_512T:
+        return SHA512_STATE_LEN_WORDS;
+    default:
+        return 0;
+    }
+}
+#endif
+
+
+/* Hash a single block */
+void sha_hal_hash_block(esp_sha_type sha_type, const void *data_block, size_t block_word_len, bool first_block)
+{
+    sha_hal_wait_idle();
+
+    sha_ll_fill_text_block(data_block, block_word_len);
+
+    /* Start hashing */
+    if (first_block) {
+        sha_ll_start_block(sha_type);
+    } else {
+        sha_ll_continue_block(sha_type);
+    }
+}
+
+#if SOC_SHA_SUPPORT_DMA
+
+#if SOC_SHA_GENERAL_DMA
+static inline void sha_hal_dma_init(lldesc_t *input)
+{
+    /* Update driver when centralized DMA interface implemented, IDF-2192 */
+    gdma_ll_tx_enable_descriptor_burst(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
+    gdma_ll_tx_enable_data_burst(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
+    gdma_ll_tx_enable_auto_write_back(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, false);
+
+    gdma_ll_tx_connect_to_periph(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, DMA_PERIPH_SHA);
+
+    /* Atleast 40 bytes when accessing external RAM */
+    gdma_ll_tx_extend_fifo_size_to(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, 40);
+    gdma_ll_tx_set_block_size_psram(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, GDMA_OUT_EXT_MEM_BK_SIZE_16B);
+
+    /* Set descriptors */
+    gdma_ll_tx_set_desc_addr(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL, (uint32_t)input);
+
+    gdma_ll_rx_reset_channel(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
+    gdma_ll_tx_reset_channel(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
+
+    /* Start transfer */
+    gdma_ll_tx_start(&GDMA, SOC_GDMA_SHA_DMA_CHANNEL);
+}
+#endif //SOC_SHA_GENERAL_DMA
+
+
+
+#if SOC_SHA_CRYPTO_DMA
+static inline void sha_hal_dma_init(lldesc_t *input)
+{
+    crypto_dma_ll_set_mode(CRYPTO_DMA_SHA);
+    crypto_dma_ll_outlink_reset();
+
+    crypto_dma_ll_outlink_set((uint32_t)input);
+    crypto_dma_ll_outlink_start();
+}
+#endif
+
+/* Hashes a number of message blocks using DMA */
+void sha_hal_hash_dma(esp_sha_type sha_type, lldesc_t *input, size_t num_blocks, bool first_block)
+{
+    sha_hal_wait_idle();
+
+    sha_hal_dma_init(input);
+
+    sha_ll_set_block_num(num_blocks);
+
+    /* Start hashing */
+    if (first_block) {
+        sha_ll_start_dma(sha_type);
+    } else {
+        sha_ll_continue_dma(sha_type);
+    }
+}
+
+#endif //SOC_SHA_SUPPORT_DMA
+
+void sha_hal_wait_idle()
+{
+    while (sha_ll_busy()) {
+    }
+}
+
+/* Reads the current message digest from the SHA engine */
+void sha_hal_read_digest(esp_sha_type sha_type, void *digest_state)
+{
+    uint32_t *digest_state_words = (uint32_t *)digest_state;
+
+    sha_ll_load(sha_type);
+    uint32_t word_len = state_length(sha_type);
+
+    sha_hal_wait_idle();
+    sha_ll_read_digest(sha_type, digest_state, word_len);
+
+    /* Fault injection check: verify SHA engine actually ran,
+       state is not all zeroes.
+    */
+    for (int i = 0; i < word_len; i++) {
+        if (digest_state_words[i] != 0) {
+            return;
+        }
+    }
+    abort(); // SHA peripheral returned all zero state, probably due to fault injection
+}
+
+#if SOC_SHA_SUPPORT_RESUME
+/* Writes the message digest to the SHA engine */
+void sha_hal_write_digest(esp_sha_type sha_type, void *digest_state)
+{
+    sha_ll_write_digest(sha_type, digest_state, state_length(sha_type));
+}
+#endif //SOC_SHA_SUPPORT_RESUME
+
+#if SOC_SHA_SUPPORT_SHA512_T
+
+/* Calculates and sets the initial digiest for SHA512_t */
+void sha_hal_sha512_init_hash(uint32_t t_string, uint8_t t_len)
+{
+    sha_ll_t_string_set(t_string);
+    sha_ll_t_len_set(t_len);
+
+    sha_ll_start_block(SHA2_512T);
+
+    sha_hal_wait_idle();
+}
+#endif //SOC_SHA_SUPPORT_SHA512_T

+ 12 - 5
components/mbedtls/CMakeLists.txt

@@ -81,13 +81,20 @@ endif()
 # Add port files to mbedtls targets
 target_sources(mbedtls PRIVATE ${mbedtls_target_sources})
 
+# Choose perihperal type
+if(CONFIG_IDF_TARGET_ESP32)
+    set(SHA_PERIPHERAL_TYPE "parallel_engine")
+else()
+    set(SHA_PERIPHERAL_TYPE "dma")
+endif()
+
 target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
                                   "${COMPONENT_DIR}/port/esp_mem.c"
                                   "${COMPONENT_DIR}/port/esp_timing.c"
-                                  "${COMPONENT_DIR}/port/esp_sha.c"
+                                  "${COMPONENT_DIR}/port/sha/esp_sha.c"
                                   "${COMPONENT_DIR}/port/esp_aes_xts.c"
                                   "${COMPONENT_DIR}/port/${idf_target}/aes.c"
-                                  "${COMPONENT_DIR}/port/${idf_target}/sha.c"
+                                  "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c"
 )
 
 if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
@@ -108,9 +115,9 @@ if(CONFIG_MBEDTLS_HARDWARE_MPI)
 endif()
 
 if(CONFIG_MBEDTLS_HARDWARE_SHA)
-    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/${idf_target}/esp_sha1.c"
-                                       "${COMPONENT_DIR}/port/${idf_target}/esp_sha256.c"
-                                       "${COMPONENT_DIR}/port/${idf_target}/esp_sha512.c"
+    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha1.c"
+                                       "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha256.c"
+                                       "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha512.c"
     )
 endif()
 

+ 6 - 2
components/mbedtls/component.mk

@@ -2,14 +2,16 @@
 # Component Makefile
 #
 
+
 COMPONENT_ADD_INCLUDEDIRS := port/include mbedtls/include esp_crt_bundle/include
 
-COMPONENT_SRCDIRS := mbedtls/library port port/$(IDF_TARGET) esp_crt_bundle
+COMPONENT_SRCDIRS := mbedtls/library port port/$(IDF_TARGET) port/sha port/sha/parallel_engine esp_crt_bundle
 
 COMPONENT_OBJEXCLUDE := mbedtls/library/net_sockets.o
 
 COMPONENT_SUBMODULES += mbedtls
 
+
 # Note: some mbedTLS hardware acceleration can be enabled/disabled by config.
 #
 # We don't need to exclude aes.o as these functions use a different prefix (esp_aes_x) and the
@@ -21,8 +23,10 @@ ifndef CONFIG_MBEDTLS_HARDWARE_MPI
     COMPONENT_OBJEXCLUDE += port/esp_bignum.o port/$(IDF_TARGET)/bignum.o
 endif
 
+
+
 ifndef CONFIG_MBEDTLS_HARDWARE_SHA
-    COMPONENT_OBJEXCLUDE += port/$(IDF_TARGET)/esp_sha1.o port/$(IDF_TARGET)/esp_sha256.o port/$(IDF_TARGET)/esp_sha512.o
+    COMPONENT_OBJEXCLUDE += port/parallel_engine/esp_sha1.o port/parallel_engine/esp_sha256.o port/parallel_engine/esp_sha512.o
 endif
 
 ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE

+ 0 - 255
components/mbedtls/port/esp32s2/esp_sha1.c

@@ -1,255 +0,0 @@
-/*
- *  SHA-1 implementation with hardware ESP32 support added.
- *  Uses mbedTLS software implementation for failover when concurrent
- *  SHA operations are in use.
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- *  Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  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.
- *
- */
-/*
- *  The SHA-1 standard was published by NIST in 1993.
- *
- *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
-
-#include "mbedtls/sha1.h"
-
-#include <string.h>
-
-#if defined(MBEDTLS_SELF_TEST)
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST */
-
-#include "esp32s2/sha.h"
-
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n )
-{
-    volatile unsigned char *p = (unsigned char *)v; while ( n-- ) *p++ = 0;
-}
-
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-}
-#endif
-
-void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
-{
-    memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
-}
-
-void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
-{
-    if ( ctx == NULL ) {
-        return;
-    }
-
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
-}
-
-void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
-                         const mbedtls_sha1_context *src )
-{
-    memcpy(dst, src, sizeof(mbedtls_sha1_context));
-}
-
-/*
- * SHA-1 context setup
- */
-int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
-{
-    ctx->total[0] = 0;
-    ctx->total[1] = 0;
-
-    memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
-    ctx->mode = SHA1;
-
-    return 0;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
-{
-    mbedtls_sha1_starts_ret( ctx );
-}
-#endif
-
-static int esp_internal_sha1_dma_process(mbedtls_sha1_context *ctx,
-        const uint8_t *data, size_t len,
-        uint8_t *buf, size_t buf_len)
-{
-    return esp_sha_dma(SHA1, data, len, buf, buf_len, ctx->first_block);
-}
-
-int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
-{
-    int ret;
-    esp_sha_acquire_hardware();
-    ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block);
-    esp_sha_release_hardware();
-    return ret;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
-                           const unsigned char data[64] )
-{
-    mbedtls_internal_sha1_process( ctx, data );
-}
-#endif
-
-int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
-{
-    int ret;
-    size_t fill;
-    uint32_t left, len, local_len = 0;
-
-    if ( !ilen || (input == NULL)) {
-        return 0;
-    }
-
-    left = ctx->total[0] & 0x3F;
-    fill = 64 - left;
-
-    ctx->total[0] += (uint32_t) ilen;
-    ctx->total[0] &= 0xFFFFFFFF;
-
-    if ( ctx->total[0] < (uint32_t) ilen ) {
-        ctx->total[1]++;
-    }
-
-    if ( left && ilen >= fill ) {
-        memcpy( (void *) (ctx->buffer + left), input, fill );
-
-        input += fill;
-        ilen  -= fill;
-        left = 0;
-        local_len = 64;
-    }
-
-    len = (ilen / 64) * 64;
-    if ( len || local_len) {
-
-        esp_sha_acquire_hardware();
-
-        if (ctx->sha_state == ESP_SHA1_STATE_INIT) {
-            ctx->first_block = true;
-            ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
-        } else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
-            ctx->first_block = false;
-            esp_sha_write_digest_state(SHA1, ctx->state);
-        }
-
-        ret = esp_internal_sha1_dma_process(ctx, input, len, ctx->buffer, local_len);
-
-        esp_sha_read_digest_state(SHA1, ctx->state);
-
-        esp_sha_release_hardware();
-
-        if (ret != 0) {
-            return ret;
-        }
-
-    }
-
-    if ( ilen > 0 ) {
-        memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
-    }
-
-    return 0;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
-                          const unsigned char *input,
-                          size_t ilen )
-{
-    mbedtls_sha1_update_ret( ctx, input, ilen );
-}
-#endif
-
-static const unsigned char sha1_padding[64] = {
-    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
-* SHA-1 final digest
- */
-int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] )
-{
-    int ret;
-    uint32_t last, padn;
-    uint32_t high, low;
-    unsigned char msglen[8];
-
-    high = ( ctx->total[0] >> 29 )
-           | ( ctx->total[1] <<  3 );
-    low  = ( ctx->total[0] <<  3 );
-
-    PUT_UINT32_BE( high, msglen, 0 );
-    PUT_UINT32_BE( low,  msglen, 4 );
-
-    last = ctx->total[0] & 0x3F;
-    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
-
-
-    if ( ( ret = mbedtls_sha1_update_ret( ctx, sha1_padding, padn ) ) != 0 ) {
-        return ret;
-    }
-    if ( ( ret = mbedtls_sha1_update_ret( ctx, msglen, 8 ) ) != 0 ) {
-        return ret;
-    }
-
-    memcpy(output, ctx->state, 20);
-
-    return ret;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
-                          unsigned char output[20] )
-{
-    mbedtls_sha1_finish_ret( ctx, output );
-}
-#endif
-
-#endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */

+ 0 - 267
components/mbedtls/port/esp32s2/esp_sha256.c

@@ -1,267 +0,0 @@
-/*
- *  SHA-256 implementation with hardware ESP32 support added.
- *  Uses mbedTLS software implementation for failover when concurrent
- *  SHA operations are in use.
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- *  Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  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.
- *
- */
-
-/*
- *  The SHA-256 Secure Hash Standard was published by NIST in 2002.
- *
- *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
-
-#include "mbedtls/sha256.h"
-
-#include <string.h>
-
-#if defined(MBEDTLS_SELF_TEST)
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST */
-
-#include "esp32s2/sha.h"
-
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n )
-{
-    volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
-}
-
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i)                            \
-do {                                                    \
-    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
-        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
-        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
-        | ( (uint32_t) (b)[(i) + 3]       );            \
-} while( 0 )
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i)                            \
-do {                                                    \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
-} while( 0 )
-#endif
-
-void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
-{
-    memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
-}
-
-void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
-{
-    if ( ctx == NULL ) {
-        return;
-    }
-
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
-}
-
-void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
-                           const mbedtls_sha256_context *src )
-{
-    *dst = *src;
-}
-
-/*
- * SHA-256 context setup
- */
-int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
-{
-    memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
-
-    if ( is224 ) {
-        ctx->mode = SHA2_224;
-    } else {
-        ctx->mode = SHA2_256;
-    }
-
-    return 0;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
-                            int is224 )
-{
-    mbedtls_sha256_starts_ret( ctx, is224 );
-}
-#endif
-
-
-int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
-{
-    int ret;
-    esp_sha_acquire_hardware();
-    ret = esp_sha_dma(ctx->mode, data, 64, 0, 0, ctx->first_block);
-    esp_sha_release_hardware();
-
-    return ret;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
-                             const unsigned char data[64] )
-{
-    mbedtls_internal_sha256_process( ctx, data );
-}
-#endif
-
-/*
- * SHA-256 process buffer
- */
-int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input,
-                               size_t ilen )
-{
-    int ret = 0;
-    size_t fill;
-    uint32_t left, len, local_len = 0;
-
-    if ( ilen == 0 ) {
-        return 0;
-    }
-
-    left = ctx->total[0] & 0x3F;
-    fill = 64 - left;
-
-    ctx->total[0] += (uint32_t) ilen;
-    ctx->total[0] &= 0xFFFFFFFF;
-
-    if ( ctx->total[0] < (uint32_t) ilen ) {
-        ctx->total[1]++;
-    }
-
-    /* Check if any data pending from previous call to this API */
-    if ( left && ilen >= fill ) {
-        memcpy( (void *) (ctx->buffer + left), input, fill );
-
-        input += fill;
-        ilen  -= fill;
-        left = 0;
-        local_len = 64;
-    }
-
-    len = (ilen / 64) * 64;
-
-    if ( len || local_len) {
-        esp_sha_acquire_hardware();
-
-        if (ctx->sha_state == ESP_SHA256_STATE_INIT) {
-            ctx->first_block = true;
-            ctx->sha_state = ESP_SHA256_STATE_IN_PROCESS;
-        } else if (ctx->sha_state == ESP_SHA256_STATE_IN_PROCESS) {
-            ctx->first_block = false;
-            esp_sha_write_digest_state(ctx->mode, ctx->state);
-        }
-
-        ret = esp_sha_dma(ctx->mode, input, len,  ctx->buffer, local_len, ctx->first_block);
-
-        esp_sha_read_digest_state(ctx->mode, ctx->state);
-
-        esp_sha_release_hardware();
-
-        if (ret != 0) {
-            return ret;
-        }
-    }
-
-    if ( ilen > 0 ) {
-        memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
-    }
-
-    return 0;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
-                            const unsigned char *input,
-                            size_t ilen )
-{
-    mbedtls_sha256_update_ret( ctx, input, ilen );
-}
-#endif
-
-static const unsigned char sha256_padding[64] = {
-    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
- * SHA-256 final digest
- */
-int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] )
-{
-    int ret;
-    uint32_t last, padn;
-    uint32_t high, low;
-    unsigned char msglen[8];
-
-    high = ( ctx->total[0] >> 29 )
-           | ( ctx->total[1] <<  3 );
-    low  = ( ctx->total[0] <<  3 );
-
-    PUT_UINT32_BE( high, msglen, 0 );
-    PUT_UINT32_BE( low,  msglen, 4 );
-
-    last = ctx->total[0] & 0x3F;
-    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
-
-    if ( ( ret = mbedtls_sha256_update_ret( ctx, sha256_padding, padn ) ) != 0 ) {
-        return ret;
-    }
-
-    if ( ( ret = mbedtls_sha256_update_ret( ctx, msglen, 8 ) ) != 0 ) {
-        return ret;
-    }
-
-    memcpy(output, ctx->state, 32);
-
-    return ret;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
-                            unsigned char output[32] )
-{
-    mbedtls_sha256_finish_ret( ctx, output );
-}
-#endif
-
-#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */

+ 0 - 317
components/mbedtls/port/esp32s3/esp_sha512.c

@@ -1,317 +0,0 @@
-/*
- *  SHA-512 implementation with hardware ESP32 support added.
- *  Uses mbedTLS software implementation for failover when concurrent
- *  SHA operations are in use.
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- *  Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  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.
- *
- */
-
-/*
- *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
- *
- *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT)
-
-#include "mbedtls/sha512.h"
-
-#if defined(_MSC_VER) || defined(__WATCOMC__)
-#define UL64(x) x##ui64
-#else
-#define UL64(x) x##ULL
-#endif
-
-#include <string.h>
-
-#if defined(MBEDTLS_SELF_TEST)
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_PLATFORM_C */
-#endif /* MBEDTLS_SELF_TEST */
-
-#include "esp32s3/sha.h"
-
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n )
-{
-    volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
-}
-
-/*
- * 64-bit integer manipulation macros (big endian)
- */
-#ifndef PUT_UINT64_BE
-#define PUT_UINT64_BE(n,b,i)                            \
-{                                                       \
-    (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
-    (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
-    (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
-    (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
-    (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
-    (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
-    (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
-    (b)[(i) + 7] = (unsigned char) ( (n)       );       \
-}
-#endif /* PUT_UINT64_BE */
-
-void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type)
-{
-    switch (type) {
-    case SHA2_384:
-    case SHA2_512224:
-    case SHA2_512256:
-    case SHA2_512T:
-        ctx->mode = type;
-        break;
-    default:
-        ctx->mode = SHA2_512;
-        break;
-    }
-}
-
-
-/* For SHA512/t mode the intial hash value will depend on t */
-void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val)
-{
-    ctx->t_val = t_val;
-}
-
-void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
-{
-    memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
-}
-
-void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
-{
-    if ( ctx == NULL ) {
-        return;
-    }
-
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
-}
-
-void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
-                           const mbedtls_sha512_context *src )
-{
-    memcpy(dst, src, sizeof(mbedtls_sha512_context));
-}
-
-/*
- * SHA-512 context setup
- */
-int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
-{
-    mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
-
-    if ( is384 ) {
-        ctx->mode = SHA2_384;
-    } else {
-        ctx->mode = SHA2_512;
-    }
-
-    return 0;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
-                            int is384 )
-{
-    mbedtls_sha512_starts_ret( ctx, is384 );
-}
-#endif
-
-static int esp_internal_sha512_dma_process(mbedtls_sha512_context *ctx,
-        const uint8_t *data, size_t len,
-        uint8_t *buf, size_t buf_len)
-{
-
-
-    return esp_sha_dma(ctx->mode, data, len, buf, buf_len, ctx->first_block);
-
-
-}
-
-int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
-{
-    int ret;
-    esp_sha_acquire_hardware();
-    ret = esp_internal_sha512_dma_process(ctx, data, 128, 0, 0);
-    esp_sha_release_hardware();
-
-    return ret;
-
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
-                             const unsigned char data[128] )
-{
-    mbedtls_internal_sha512_process( ctx, data );
-}
-#endif
-
-/*
- * SHA-512 process buffer
- */
-int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input,
-                               size_t ilen )
-{
-    int ret;
-    size_t fill;
-    unsigned int left, len, local_len = 0;
-
-    if ( ilen == 0 ) {
-        return 0;
-    }
-
-    left = (unsigned int) (ctx->total[0] & 0x7F);
-    fill = 128 - left;
-
-    ctx->total[0] += (uint64_t) ilen;
-
-    if ( ctx->total[0] < (uint64_t) ilen ) {
-        ctx->total[1]++;
-    }
-
-    if ( left && ilen >= fill ) {
-        memcpy( (void *) (ctx->buffer + left), input, fill );
-
-        input += fill;
-        ilen  -= fill;
-        left = 0;
-        local_len = 128;
-    }
-
-    len = (ilen / 128) * 128;
-
-    if ( len || local_len) {
-
-        esp_sha_acquire_hardware();
-
-        if (ctx->sha_state == ESP_SHA512_STATE_INIT) {
-
-            if (ctx->mode == SHA2_512T) {
-                esp_sha_512_t_init_hash(ctx->t_val);
-                ctx->first_block = false;
-            } else {
-                ctx->first_block = true;
-            }
-            ctx->sha_state = ESP_SHA512_STATE_IN_PROCESS;
-
-        } else if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) {
-            ctx->first_block = false;
-            esp_sha_write_digest_state(ctx->mode, ctx->state);
-        }
-
-        ret = esp_internal_sha512_dma_process(ctx, input, len, ctx->buffer, local_len);
-
-        esp_sha_read_digest_state(ctx->mode, ctx->state);
-
-        esp_sha_release_hardware();
-
-        if (ret != 0) {
-            return ret;
-        }
-
-    }
-
-
-    if ( ilen > 0 ) {
-        memcpy( (void *) (ctx->buffer + left), input + len, ilen - len );
-    }
-
-    return 0;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
-                            const unsigned char *input,
-                            size_t ilen )
-{
-    mbedtls_sha512_update_ret( ctx, input, ilen );
-}
-#endif
-
-
-static const unsigned char sha512_padding[128] = {
-    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
- * SHA-512 final digest
- */
-int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] )
-{
-    int ret;
-    size_t last, padn;
-    uint64_t high, low;
-    unsigned char msglen[16];
-
-    high = ( ctx->total[0] >> 61 )
-           | ( ctx->total[1] <<  3 );
-    low  = ( ctx->total[0] <<  3 );
-
-    PUT_UINT64_BE( high, msglen, 0 );
-    PUT_UINT64_BE( low,  msglen, 8 );
-
-    last = (size_t)( ctx->total[0] & 0x7F );
-    padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
-
-    if ( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 ) {
-        return ret;
-    }
-
-    if ( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 ) {
-        return ret;
-    }
-
-    if (ctx->mode == SHA2_384) {
-        memcpy(output, ctx->state, 48);
-    } else {
-        memcpy(output, ctx->state, 64);
-    }
-
-    return ret;
-}
-
-#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
-                            unsigned char output[64] )
-{
-    mbedtls_sha512_finish_ret( ctx, output );
-}
-#endif
-
-#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */

+ 0 - 384
components/mbedtls/port/esp32s3/sha.c

@@ -1,384 +0,0 @@
-/*
- *  ESP32 hardware accelerated SHA1/256/512 implementation
- *  based on mbedTLS FIPS-197 compliant version.
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- *  Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE Ltd
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  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.
- *
- */
-/*
- *  The SHA-1 standard was published by NIST in 1993.
- *
- *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
- */
-
-typedef int _lock_t;
-
-#include <string.h>
-#include <stdio.h>
-#include <sys/lock.h>
-#include "esp_err.h"
-#include "esp_log.h"
-#include "esp32s3/rom/ets_sys.h"
-#include "soc/dport_reg.h"
-#include "soc/hwcrypto_reg.h"
-#include "soc/soc_memory_layout.h"
-
-#include "esp32s3/rom/cache.h"
-
-#include "soc/cache_memory.h"
-
-#include "freertos/FreeRTOS.h"
-#include "freertos/semphr.h"
-
-#include "esp32s3/sha.h"
-#include "esp32s3/rom/lldesc.h"
-#include "soc/periph_defs.h"
-#include "driver/periph_ctrl.h"
-#include "sys/param.h"
-#include "soc/gdma_struct.h"
-#include "soc/extmem_reg.h"
-
-#define DMA_PERIPH_AES 6 /* DMA peripheral indexes */
-#define DMA_PERIPH_SHA 7
-#define DMA_CHANNEL 1 /* note: hard-coded */
-
-/* Max amount of bytes in a single DMA operation is 4095,
-   for SHA this means that the biggest safe amount of bytes is
-   31 blocks of 128 bytes = 3968
-*/
-#define SHA_DMA_MAX_BYTES 3968
-
-/* Lock for SHA engine */
-static _lock_t s_sha_lock;
-
-const static char *TAG = "esp-sha";
-
-inline static size_t block_length(esp_sha_type type)
-{
-    switch (type) {
-    case SHA1:
-    case SHA2_224:
-    case SHA2_256:
-        return 64;
-    case SHA2_384:
-    case SHA2_512:
-    case SHA2_512224:
-    case SHA2_512256:
-    case SHA2_512T:
-        return 128;
-    default:
-        return 0;
-    }
-}
-
-/* Return state size (in bytes) for a given SHA type */
-inline static size_t state_length(esp_sha_type type)
-{
-    switch (type) {
-    case SHA1:
-        return 160 / 8;
-    case SHA2_224:
-    case SHA2_256:
-        return 256 / 8;
-    case SHA2_384:
-    case SHA2_512:
-    case SHA2_512224:
-    case SHA2_512256:
-    case SHA2_512T:
-        return 512 / 8;
-    default:
-        return 0;
-    }
-}
-
-/* Enable SHA peripheral and then lock it */
-void esp_sha_acquire_hardware()
-{
-    _lock_acquire(&s_sha_lock);
-
-    /* Enable SHA and DMA hardware */
-    //periph_module_enable(PERIPH_SHA_DMA_MODULE);
-    REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_CRYPTO_SHA_CLK_EN | SYSTEM_DMA_CLK_EN);
-    REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_CRYPTO_SHA_RST | SYSTEM_CRYPTO_HMAC_RST |
-                SYSTEM_DMA_RST | SYSTEM_CRYPTO_DS_RST);
-
-
-}
-
-/* Disable SHA peripheral block and then release it */
-void esp_sha_release_hardware()
-{
-    /* Disable SHA and DMA hardware */
-    //periph_module_disable(PERIPH_SHA_MODULE);
-    REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_CRYPTO_SHA_RST | SYSTEM_DMA_RST |
-                SYSTEM_CRYPTO_DS_RST);
-    REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_CRYPTO_SHA_CLK_EN | SYSTEM_DMA_CLK_EN);
-
-    _lock_release(&s_sha_lock);
-
-}
-
-
-/* Busy wait until SHA is idle */
-static void esp_sha_wait_idle(void)
-{
-    while (DPORT_REG_READ(SHA_BUSY_REG) != 0) {
-    }
-}
-
-
-void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
-{
-    uint32_t *digest_state_words = (uint32_t *)digest_state;
-    uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
-
-    for (int i = 0; i < state_length(sha_type) / 4; i++) {
-        REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
-    }
-}
-
-/* Read the SHA digest from hardware */
-void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
-{
-    uint32_t *digest_state_words = (uint32_t *)digest_state;
-    int word_len = state_length(sha_type) / 4;
-
-    esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, word_len);
-
-    /* Fault injection check: verify SHA engine actually ran,
-       state is not all zeroes.
-    */
-    for (int i = 0; i < word_len; i++) {
-        if (digest_state_words[i] != 0) {
-            return;
-        }
-    }
-    abort(); // SHA peripheral returned all zero state, probably due to fault injection
-}
-
-
-static int esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
-                               const void *buf, uint32_t buf_len, bool is_first_block);
-
-/* Performs SHA on multiple blocks at a time using DMA
-   splits up into smaller operations for inputs that exceed a single DMA list
- */
-int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
-                const void *buf, uint32_t buf_len, bool is_first_block)
-{
-    int ret = 0;
-    const void *dma_input;
-    unsigned char *non_icache_input = NULL;
-    unsigned char *non_icache_buf = NULL;
-    int dma_op_num = ( ilen / (SHA_DMA_MAX_BYTES + 1) ) + 1;
-
-    if (buf_len > 128) {
-        ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block");
-        return -1;
-    }
-
-    /* DMA cannot access memory in the iCache range, copy data to temporary buffers before transfer */
-    if (!esp_ptr_dma_capable(input) && ilen) {
-        non_icache_input = malloc(sizeof(unsigned char) * MIN(ilen, SHA_DMA_MAX_BYTES));
-        if (non_icache_input == NULL) {
-            ESP_LOGE(TAG, "Failed to allocate memory");
-            ret = ESP_ERR_NO_MEM;
-            goto cleanup;
-        }
-    }
-
-    if (!esp_ptr_dma_capable(buf) && buf_len) {
-        non_icache_buf = malloc(sizeof(unsigned char) * buf_len);
-        if (non_icache_buf == NULL) {
-            ESP_LOGE(TAG, "Failed to allocate memory");
-            ret = ESP_ERR_NO_MEM;
-            goto cleanup;
-        }
-        memcpy(non_icache_buf, buf, buf_len);
-        buf = non_icache_buf;
-    }
-
-    /* The max amount of blocks in a single hardware operation is 2^6 - 1 = 63
-       Thus we only do a single DMA input list + dma buf list,
-       which is max 3968/64 + 64/64 = 63 blocks */
-    for (int i = 0; i < dma_op_num; i++) {
-        int dma_chunk_len = MIN(ilen, SHA_DMA_MAX_BYTES);
-
-
-        /* Input depends on if it's a temp alloc buffer or supplied by user */
-        if (non_icache_input != NULL) {
-            memcpy(non_icache_input, input, dma_chunk_len);
-            dma_input = non_icache_input;
-        } else {
-            dma_input = input;
-        }
-
-        ret = esp_sha_dma_process(sha_type, dma_input, dma_chunk_len, buf, buf_len, is_first_block);
-
-
-        if (ret != 0) {
-            return ret;
-        }
-
-        is_first_block = false;
-
-
-        ilen -= dma_chunk_len;
-        input += dma_chunk_len;
-
-        // Only append buf to the first operation
-        buf_len = 0;
-    }
-
-cleanup:
-    free(non_icache_input);
-    free(non_icache_buf);
-    return ret;
-}
-
-static void esp_sha_dma_init(lldesc_t *input)
-{
-    /* Reset DMA */
-    REG_CLR_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
-    REG_SET_BIT(SYSTEM_PERIP_CLK_EN1_REG, SYSTEM_DMA_CLK_EN);
-    REG_SET_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
-    REG_CLR_BIT(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
-
-    /* NOTE: all hardcoded to DMA channel 1 */
-    /* Note: burst mode has alignment requirements that we have not checked here */
-    GDMA.conf0[0].outdscr_burst_en = 0; /* was 1*/
-    GDMA.conf0[0].out_data_burst_en = 0; /* was 1*/
-    GDMA.conf0[0].out_auto_wrback = 0;
-
-    GDMA.peri_sel[0].peri_out_sel = DMA_PERIPH_SHA;
-
-    GDMA.sram_size[0].in_size = 3; /* 40 bytes, also minimum size for EDMA */
-    GDMA.sram_size[0].out_size = 3;
-    GDMA.conf1[0].in_ext_mem_bk_size = 0; // 16 bytes
-    GDMA.conf1[0].out_ext_mem_bk_size = 0; // 16 bytes
-
-    /* Set descriptors */
-    GDMA.out_link[0].addr = (uint32_t)input;
-
-    GDMA.conf0[0].in_rst = 1;
-    GDMA.conf0[0].in_rst = 0;
-    GDMA.conf0[0].out_rst = 1;
-    GDMA.conf0[0].out_rst = 0;
-
-    /* Start transfer */
-    GDMA.out_link[0].start = 1;
-}
-
-/* The initial hash value for SHA512/t is generated according to the
-   algorithm described in the TRM, chapter SHA-Accelerator
-*/
-int esp_sha_512_t_init_hash(uint16_t t)
-{
-    uint32_t t_string = 0;
-    uint8_t t0, t1, t2, t_len;
-
-    if (t == 384) {
-        ESP_LOGE(TAG, "Invalid t for SHA512/t, t = %u,cannot be 384", t);
-        return -1;
-    }
-
-    if (t <= 9) {
-        t_string = (uint32_t)((1 << 23) | ((0x30 + t) << 24));
-        t_len = 0x48;
-    } else if (t <= 99) {
-        t0 = t % 10;
-        t1 = (t / 10) % 10;
-        t_string = (uint32_t)((1 << 15) | ((0x30 + t0) << 16) |
-                              (((0x30 + t1) << 24)));
-        t_len = 0x50;
-    } else if (t <= 512) {
-        t0 = t % 10;
-        t1 = (t / 10) % 10;
-        t2 = t / 100;
-        t_string = (uint32_t)((1 << 7) | ((0x30 + t0) << 8) |
-                              (((0x30 + t1) << 16) + ((0x30 + t2) << 24)));
-        t_len = 0x58;
-    } else {
-        ESP_LOGE(TAG, "Invalid t for SHA512/t, t = %u, must equal or less than 512", t);
-        return -1;
-    }
-
-    REG_WRITE(SHA_T_LENGTH_REG, t_len);
-    REG_WRITE(SHA_T_STRING_REG, t_string);
-    REG_WRITE(SHA_MODE_REG, SHA2_512T);
-    REG_WRITE(SHA_START_REG, 1);
-
-    esp_sha_wait_idle();
-
-    return 0;
-}
-
-/* Performs SHA on multiple blocks at a time */
-static int esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
-                               const void *buf, uint32_t buf_len, bool is_first_block)
-{
-    size_t blk_len = 0;
-    int ret = 0;
-    lldesc_t dma_descr_input = {};
-    lldesc_t dma_descr_buf = {};
-    lldesc_t *dma_descr_head;
-
-    blk_len = block_length(sha_type);
-
-    REG_WRITE(SHA_MODE_REG, sha_type);
-    REG_WRITE(SHA_BLOCK_NUM_REG, ((ilen + buf_len) / blk_len));
-
-
-    /* DMA descriptor for Memory to DMA-SHA transfer */
-    if (ilen) {
-        dma_descr_input.length = ilen;
-        dma_descr_input.size = ilen;
-        dma_descr_input.owner = 1;
-        dma_descr_input.eof = 1;
-        dma_descr_input.buf = (void *)input;
-        dma_descr_head = &dma_descr_input;
-    }
-    /* Check after input to overide head if there is any buf*/
-    if (buf_len) {
-        dma_descr_buf.length = buf_len;
-        dma_descr_buf.size = buf_len;
-        dma_descr_buf.owner = 1;
-        dma_descr_buf.eof = 1;
-        dma_descr_buf.buf = (void *)buf;
-        dma_descr_head = &dma_descr_buf;
-    }
-
-    /* Link DMA lists */
-    if (buf_len && ilen) {
-        dma_descr_buf.eof = 0;
-        dma_descr_buf.empty = (uint32_t)(&dma_descr_input);
-    }
-
-    esp_sha_dma_init(dma_descr_head);
-
-    /* Start hashing */
-    if (is_first_block) {
-        REG_WRITE(SHA_DMA_START_REG, 1);
-    } else {
-        REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
-    }
-
-    esp_sha_wait_idle();
-
-    return ret;
-}
-

+ 4 - 195
components/mbedtls/port/include/esp32/sha.h

@@ -1,4 +1,4 @@
-// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2019-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.
@@ -11,201 +11,10 @@
 // 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.
-#ifndef _ESP_SHA_H_
-#define _ESP_SHA_H_
 
-#include "esp32/rom/sha.h"
-#include "esp_types.h"
+#pragma once
 
-/** @brief Low-level support functions for the hardware SHA engine
- *
- * @note If you're looking for a SHA API to use, try mbedtls component
- * mbedtls/shaXX.h. That API supports hardware acceleration.
- *
- * The API in this header provides some building blocks for implementing a
- * full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
- *
- * Some technical details about the hardware SHA engine:
- *
- * - SHA accelerator engine calculates one digest at a time, per SHA
- *   algorithm type. It initialises and maintains the digest state
- *   internally. It is possible to read out an in-progress SHA digest
- *   state, but it is not possible to restore a SHA digest state
- *   into the engine.
- *
- * - The memory block SHA_TEXT_BASE is shared between all SHA digest
- *   engines, so all engines must be idle before this memory block is
- *   modified.
- *
- */
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Defined in esp32/rom/sha.h */
-typedef enum SHA_TYPE esp_sha_type;
-
-/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
- *
- * @note For more versatile SHA calculations, where data doesn't need
- * to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. The
- * hardware-accelerated mbedTLS implementation is also faster when
- * hashing large amounts of data.
- *
- * @note It is not necessary to lock any SHA hardware before calling
- * this function, thread safety is managed internally.
- *
- * @note If a TLS connection is open then this function may block
- * indefinitely waiting for a SHA engine to become available. Use the
- * mbedTLS SHA API to avoid this problem.
- *
- * @param sha_type SHA algorithm to use.
- *
- * @param input Input data buffer.
- *
- * @param ilen Length of input data in bytes.
- *
- * @param output Buffer for output SHA digest. Output is 20 bytes for
- * sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
- * sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
- */
-void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
-
-/* @brief Begin to execute a single SHA block operation
- *
- * @note This is a piece of a SHA algorithm, rather than an entire SHA
- * algorithm.
- *
- * @note Call esp_sha_try_lock_engine() before calling this
- * function. Do not call esp_sha_lock_memory_block() beforehand, this
- * is done inside the function.
- *
- * @param sha_type SHA algorithm to use.
- *
- * @param data_block Pointer to block of data. Block size is
- * determined by algorithm (SHA1/SHA2_256 = 64 bytes,
- * SHA2_384/SHA2_512 = 128 bytes)
- *
- * @param is_first_block If this parameter is true, the SHA state will
- * be initialised (with the initial state of the given SHA algorithm)
- * before the block is calculated. If false, the existing state of the
- * SHA engine will be used.
- *
- * @return As a performance optimisation, this function returns before
- * the SHA block operation is complete. Both this function and
- * esp_sha_read_state() will automatically wait for any previous
- * operation to complete before they begin. If using the SHA registers
- * directly in another way, call esp_sha_wait_idle() after calling this
- * function but before accessing the SHA registers.
- */
-void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
-
-/** @brief Read out the current state of the SHA digest loaded in the engine.
- *
- * @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
- *
- * @note Call esp_sha_try_lock_engine() before calling this
- * function. Do not call esp_sha_lock_memory_block() beforehand, this
- * is done inside the function.
- *
- * If the SHA suffix padding block has been executed already, the
- * value that is read is the SHA digest (in big endian
- * format). Otherwise, the value that is read is an interim SHA state.
- *
- * @note If sha_type is SHA2_384, only 48 bytes of state will be read.
- * This is enough for the final SHA2_384 digest, but if you want the
- * interim SHA-384 state (to continue digesting) then pass SHA2_512 instead.
- *
- * @param sha_type SHA algorithm in use.
- *
- * @param state Pointer to a memory buffer to hold the SHA state. Size
- * is 20 bytes (SHA1), 32 bytes (SHA2_256), 48 bytes (SHA2_384) or 64 bytes (SHA2_512).
- *
- */
-void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
-
-/**
- * @brief Obtain exclusive access to a particular SHA engine
- *
- * @param sha_type Type of SHA engine to use.
- *
- * Blocks until engine is available. Note: Can block indefinitely
- * while a TLS connection is open, suggest using
- * esp_sha_try_lock_engine() and failing over to software SHA.
- */
-void esp_sha_lock_engine(esp_sha_type sha_type);
-
-/**
- * @brief Try and obtain exclusive access to a particular SHA engine
- *
- * @param sha_type Type of SHA engine to use.
- *
- * @return Returns true if the SHA engine is locked for exclusive
- * use. Call esp_sha_unlock_sha_engine() when done.  Returns false if
- * the SHA engine is already in use, caller should use software SHA
- * algorithm for this digest.
- */
-bool esp_sha_try_lock_engine(esp_sha_type sha_type);
-
-/**
- * @brief Unlock an engine previously locked with esp_sha_lock_engine() or esp_sha_try_lock_engine()
- *
- * @param sha_type Type of engine to release.
- */
-void esp_sha_unlock_engine(esp_sha_type sha_type);
-
-/**
- * @brief Acquire exclusive access to the SHA shared memory block at SHA_TEXT_BASE
- *
- * This memory block is shared across all the SHA algorithm types.
- *
- * Caller should have already locked a SHA engine before calling this function.
- *
- * Note that it is possible to obtain exclusive access to the memory block even
- * while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
- * to ensure the SHA engine is not reading from the memory block in hardware.
- *
- * @note This function enters a critical section. Do not block while holding this lock.
- *
- * @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
- *
- * Call esp_sha_unlock_memory_block() when done.
- */
-void esp_sha_lock_memory_block(void);
-
-/**
- * @brief Release exclusive access to the SHA register memory block at SHA_TEXT_BASE
- *
- * Caller should have already locked a SHA engine before calling this function.
- *
- * This function releases the critical section entered by esp_sha_lock_memory_block().
- *
- * Call following esp_sha_lock_memory_block().
- */
-void esp_sha_unlock_memory_block(void);
-
-/** @brief Wait for the SHA engine to finish any current operation
- *
- * @note This function does not ensure exclusive access to any SHA
- * engine. Caller should use esp_sha_try_lock_engine() and
- * esp_sha_lock_memory_block() as required.
- *
- * @note Functions declared in this header file wait for SHA engine
- * completion automatically, so you don't need to use this API for
- * these. However if accessing SHA registers directly, you will need
- * to call this before accessing SHA registers if using the
- * esp_sha_block() function.
- *
- * @note This function busy-waits, so wastes CPU resources.
- * Best to delay calling until you are about to need it.
- *
- */
-void esp_sha_wait_idle(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+#include "sha/sha_parallel_engine.h"
 
+#warning esp32/sha.h is deprecated, please use sha_parallel_engine.h instead

+ 3 - 150
components/mbedtls/port/include/esp32s2/sha.h

@@ -12,157 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef _ESP_SHA_H_
-#define _ESP_SHA_H_
+#pragma once
 
-#include "esp32s2/rom/sha.h"
+#include "sha/sha_dma.h"
 
-/** @brief Low-level support functions for the hardware SHA engine using DMA
- *
- * @note If you're looking for a SHA API to use, try mbedtls component
- * mbedtls/shaXX.h. That API supports hardware acceleration.
- *
- * The API in this header provides some building blocks for implementing a
- * full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
- *
- * Some technical details about the hardware SHA engine:
- *
- * - The crypto DMA is shared between the SHA and AES engine, it is not
- *   possible for them to run calcalutions in parallel.
- *
- */
+#warning esp32s2/sha.h is deprecated, please use sha/sha_dma.h instead
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Defined in rom/sha.h */
-typedef SHA_TYPE esp_sha_type;
-
-/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
- *
- * @note For more versatile SHA calculations, where data doesn't need
- * to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs.
- *
- * @note It is not necessary to lock any SHA hardware before calling
- * this function, thread safety is managed internally.
- *
- * @param sha_type SHA algorithm to use.
- *
- * @param input Input data buffer.
- *
- * @param ilen Length of input data in bytes.
- *
- * @param output Buffer for output SHA digest. Output is 20 bytes for
- * sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
- * sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
- */
-void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
-
-/** @brief Execute SHA block operation using DMA
- *
- * @note This is a piece of a SHA algorithm, rather than an entire SHA
- * algorithm.
- *
- * @note Call esp_sha_aquire_hardware() before calling this
- * function.
- *
- * @param sha_type SHA algorithm to use.
- *
- * @param input Pointer to the input data. Block size is
- * determined by algorithm (SHA1/SHA2_256 = 64 bytes,
- * SHA2_384/SHA2_512 = 128 bytes)
- *
- * @param ilen length of input data should be multiple of block length.
- *
- * @param buf Pointer to blocks of data that will be prepended
- * to data_block before hashing. Useful when there is two sources of
- * data that need to be efficiently calculated in a single SHA DMA
- * operation.
- *
- * @param buf_len length of buf data should be multiple of block length.
- * Should not be longer than the maximum amount of bytes in a single block
- * (128 bytes)
- *
- * @param is_first_block If this parameter is true, the SHA state will
- * be initialised (with the initial state of the given SHA algorithm)
- * before the block is calculated. If false, the existing state of the
- * SHA engine will be used.
- *
- * @param t The number of bits for the SHA512/t hash function, with
- * output truncated to t bits. Used for calculating the inital hash.
- * t is any positive integer between 1 and 512, except 384.
- *
- * @return 0 if successful
- */
-int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
-                const void *buf, uint32_t buf_len, bool is_first_block);
-
-/**
- * @brief Read out the current state of the SHA digest
- *
- * @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
- *
- * @note Call esp_sha_aquire_hardware() before calling this
- * function.
- *
- * If the SHA suffix padding block has been executed already, the
- * value that is read is the SHA digest.
- * Otherwise, the value that is read is an interim SHA state.
- *
- * @param sha_type SHA algorithm in use.
- * @param digest_state Pointer to a memory buffer to hold the SHA state. Size
- * is 20 bytes (SHA1), 32 bytes (SHA2_256), or 64 bytes (SHA2_384, SHA2_512).
- */
-void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
-
-/**
- * @brief Set the current state of the SHA digest
- *
- * @note Call esp_sha_aquire_hardware() before calling this
- * function.
- *
- * When resuming a
- *
- * @param sha_type SHA algorithm in use.
- * @param digest_state
- */
-void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state);
-
-
-/**
- * @brief Enables the SHA and crypto DMA peripheral and takes the
- * locks for both of them.
- */
-void esp_sha_acquire_hardware(void);
-
-/**
- * @brief Disables the SHA and crypto DMA peripheral and releases the
- * locks.
- */
-void esp_sha_release_hardware(void);
-
-/*
-*/
-
-/**
- * @brief Sets the initial hash value for SHA512/t.
- *
- * @note Is generated according to the algorithm described in the TRM,
- * chapter SHA-Accelerator
- *
- * @note The engine must be locked until the value is used for an operation
- * or read out. Else you risk another operation overwriting it.
- *
- * @param t
- *
- * @return 0 if successful
- */
-int esp_sha_512_t_init_hash(uint16_t t);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
 

+ 3 - 7
components/mbedtls/port/include/esp32s3/sha.h → components/mbedtls/port/include/sha/sha_dma.h

@@ -3,7 +3,7 @@
 // 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
@@ -12,10 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef _ESP_SHA_H_
-#define _ESP_SHA_H_
+#pragma once
 
-#include "esp32s3/rom/sha.h"
+#include "hal/sha_types.h"
 
 /** @brief Low-level support functions for the hardware SHA engine using DMA
  *
@@ -36,8 +35,6 @@
 extern "C" {
 #endif
 
-/* Defined in rom/sha.h */
-typedef SHA_TYPE esp_sha_type;
 
 /** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
  *
@@ -161,5 +158,4 @@ int esp_sha_512_t_init_hash(uint16_t t);
 }
 #endif
 
-#endif
 

+ 207 - 0
components/mbedtls/port/include/sha/sha_parallel_engine.h

@@ -0,0 +1,207 @@
+// Copyright 2015-2016 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.
+#pragma once
+
+#include "hal/sha_types.h"
+#include "esp_types.h"
+
+/** @brief Low-level support functions for the hardware SHA engine
+ *
+ * @note If you're looking for a SHA API to use, try mbedtls component
+ * mbedtls/shaXX.h. That API supports hardware acceleration.
+ *
+ * The API in this header provides some building blocks for implementing a
+ * full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
+ *
+ * Some technical details about the hardware SHA engine:
+ *
+ * - SHA accelerator engine calculates one digest at a time, per SHA
+ *   algorithm type. It initialises and maintains the digest state
+ *   internally. It is possible to read out an in-progress SHA digest
+ *   state, but it is not possible to restore a SHA digest state
+ *   into the engine.
+ *
+ * - The memory block SHA_TEXT_BASE is shared between all SHA digest
+ *   engines, so all engines must be idle before this memory block is
+ *   modified.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
+ *
+ * @note For more versatile SHA calculations, where data doesn't need
+ * to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. The
+ * hardware-accelerated mbedTLS implementation is also faster when
+ * hashing large amounts of data.
+ *
+ * @note It is not necessary to lock any SHA hardware before calling
+ * this function, thread safety is managed internally.
+ *
+ * @note If a TLS connection is open then this function may block
+ * indefinitely waiting for a SHA engine to become available. Use the
+ * mbedTLS SHA API to avoid this problem.
+ *
+ * @param sha_type SHA algorithm to use.
+ *
+ * @param input Input data buffer.
+ *
+ * @param ilen Length of input data in bytes.
+ *
+ * @param output Buffer for output SHA digest. Output is 20 bytes for
+ * sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
+ * sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
+ */
+void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
+
+/* @brief Begin to execute a single SHA block operation
+ *
+ * @note This is a piece of a SHA algorithm, rather than an entire SHA
+ * algorithm.
+ *
+ * @note Call esp_sha_try_lock_engine() before calling this
+ * function. Do not call esp_sha_lock_memory_block() beforehand, this
+ * is done inside the function.
+ *
+ * @param sha_type SHA algorithm to use.
+ *
+ * @param data_block Pointer to block of data. Block size is
+ * determined by algorithm (SHA1/SHA2_256 = 64 bytes,
+ * SHA2_384/SHA2_512 = 128 bytes)
+ *
+ * @param is_first_block If this parameter is true, the SHA state will
+ * be initialised (with the initial state of the given SHA algorithm)
+ * before the block is calculated. If false, the existing state of the
+ * SHA engine will be used.
+ *
+ * @return As a performance optimisation, this function returns before
+ * the SHA block operation is complete. Both this function and
+ * esp_sha_read_state() will automatically wait for any previous
+ * operation to complete before they begin. If using the SHA registers
+ * directly in another way, call esp_sha_wait_idle() after calling this
+ * function but before accessing the SHA registers.
+ */
+void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
+
+/** @brief Read out the current state of the SHA digest loaded in the engine.
+ *
+ * @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
+ *
+ * @note Call esp_sha_try_lock_engine() before calling this
+ * function. Do not call esp_sha_lock_memory_block() beforehand, this
+ * is done inside the function.
+ *
+ * If the SHA suffix padding block has been executed already, the
+ * value that is read is the SHA digest (in big endian
+ * format). Otherwise, the value that is read is an interim SHA state.
+ *
+ * @note If sha_type is SHA2_384, only 48 bytes of state will be read.
+ * This is enough for the final SHA2_384 digest, but if you want the
+ * interim SHA-384 state (to continue digesting) then pass SHA2_512 instead.
+ *
+ * @param sha_type SHA algorithm in use.
+ *
+ * @param state Pointer to a memory buffer to hold the SHA state. Size
+ * is 20 bytes (SHA1), 32 bytes (SHA2_256), 48 bytes (SHA2_384) or 64 bytes (SHA2_512).
+ *
+ */
+void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
+
+/**
+ * @brief Obtain exclusive access to a particular SHA engine
+ *
+ * @param sha_type Type of SHA engine to use.
+ *
+ * Blocks until engine is available. Note: Can block indefinitely
+ * while a TLS connection is open, suggest using
+ * esp_sha_try_lock_engine() and failing over to software SHA.
+ */
+void esp_sha_lock_engine(esp_sha_type sha_type);
+
+/**
+ * @brief Try and obtain exclusive access to a particular SHA engine
+ *
+ * @param sha_type Type of SHA engine to use.
+ *
+ * @return Returns true if the SHA engine is locked for exclusive
+ * use. Call esp_sha_unlock_sha_engine() when done.  Returns false if
+ * the SHA engine is already in use, caller should use software SHA
+ * algorithm for this digest.
+ */
+bool esp_sha_try_lock_engine(esp_sha_type sha_type);
+
+/**
+ * @brief Unlock an engine previously locked with esp_sha_lock_engine() or esp_sha_try_lock_engine()
+ *
+ * @param sha_type Type of engine to release.
+ */
+void esp_sha_unlock_engine(esp_sha_type sha_type);
+
+/**
+ * @brief Acquire exclusive access to the SHA shared memory block at SHA_TEXT_BASE
+ *
+ * This memory block is shared across all the SHA algorithm types.
+ *
+ * Caller should have already locked a SHA engine before calling this function.
+ *
+ * Note that it is possible to obtain exclusive access to the memory block even
+ * while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
+ * to ensure the SHA engine is not reading from the memory block in hardware.
+ *
+ * @note This function enters a critical section. Do not block while holding this lock.
+ *
+ * @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
+ *
+ * Call esp_sha_unlock_memory_block() when done.
+ */
+void esp_sha_lock_memory_block(void);
+
+/**
+ * @brief Release exclusive access to the SHA register memory block at SHA_TEXT_BASE
+ *
+ * Caller should have already locked a SHA engine before calling this function.
+ *
+ * This function releases the critical section entered by esp_sha_lock_memory_block().
+ *
+ * Call following esp_sha_lock_memory_block().
+ */
+void esp_sha_unlock_memory_block(void);
+
+/** @brief Wait for the SHA engine to finish any current operation
+ *
+ * @note This function does not ensure exclusive access to any SHA
+ * engine. Caller should use esp_sha_try_lock_engine() and
+ * esp_sha_lock_memory_block() as required.
+ *
+ * @note Functions declared in this header file wait for SHA engine
+ * completion automatically, so you don't need to use this API for
+ * these. However if accessing SHA registers directly, you will need
+ * to call this before accessing SHA registers if using the
+ * esp_sha_block() function.
+ *
+ * @note This function busy-waits, so wastes CPU resources.
+ * Best to delay calling until you are about to need it.
+ *
+ */
+void esp_sha_wait_idle(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+

+ 13 - 36
components/mbedtls/port/include/sha1_alt.h

@@ -23,19 +23,22 @@
 #ifndef _SHA1_ALT_H_
 #define _SHA1_ALT_H_
 
+#if defined(MBEDTLS_SHA1_ALT)
+
+#include "hal/sha_types.h"
+#include "soc/sha_caps.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if defined(MBEDTLS_SHA1_ALT)
-
-#if CONFIG_IDF_TARGET_ESP32S3
+#if SOC_SHA_SUPPORT_PARALLEL_ENG
 
-#include "esp32s3/sha.h"
 typedef enum {
-    ESP_SHA1_STATE_INIT,
-    ESP_SHA1_STATE_IN_PROCESS
-} esp_sha1_state;
+    ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */
+    ESP_MBEDTLS_SHA1_HARDWARE, /* using hardware SHA engine */
+    ESP_MBEDTLS_SHA1_SOFTWARE, /* using software SHA */
+} esp_mbedtls_sha1_mode;
 
 /**
  * \brief          SHA-1 context structure
@@ -44,16 +47,11 @@ typedef struct {
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[5];          /*!< intermediate digest state  */
     unsigned char buffer[64];   /*!< data block being processed */
-    int first_block;            /*!< if first then true else false */
-    esp_sha_type mode;
-    esp_sha1_state sha_state;
+    esp_mbedtls_sha1_mode mode;
 } mbedtls_sha1_context;
 
-#endif //CONFIG_IDF_TARGET_ESP32S3
+#elif SOC_SHA_SUPPORT_DMA
 
-#if CONFIG_IDF_TARGET_ESP32S2
-
-#include "esp32s2/sha.h"
 typedef enum {
     ESP_SHA1_STATE_INIT,
     ESP_SHA1_STATE_IN_PROCESS
@@ -71,28 +69,7 @@ typedef struct {
     esp_sha1_state sha_state;
 } mbedtls_sha1_context;
 
-#endif //CONFIG_IDF_TARGET_ESP32S2
-
-#if CONFIG_IDF_TARGET_ESP32
-
-typedef enum {
-    ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */
-    ESP_MBEDTLS_SHA1_HARDWARE, /* using hardware SHA engine */
-    ESP_MBEDTLS_SHA1_SOFTWARE, /* using software SHA */
-} esp_mbedtls_sha1_mode;
-
-/**
- * \brief          SHA-1 context structure
- */
-typedef struct {
-    uint32_t total[2];          /*!< number of bytes processed  */
-    uint32_t state[5];          /*!< intermediate digest state  */
-    unsigned char buffer[64];   /*!< data block being processed */
-    esp_mbedtls_sha1_mode mode;
-}
-mbedtls_sha1_context;
-
-#endif //CONFIG_IDF_TARGET_ESP32
+#endif
 
 #endif
 

+ 16 - 45
components/mbedtls/port/include/sha256_alt.h

@@ -23,20 +23,21 @@
 #ifndef _SHA256_ALT_H_
 #define _SHA256_ALT_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #if defined(MBEDTLS_SHA256_ALT)
 
-#if CONFIG_IDF_TARGET_ESP32S3
+#include "hal/sha_types.h"
+#include "soc/sha_caps.h"
 
-#include "esp32s3/sha.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+#if SOC_SHA_SUPPORT_PARALLEL_ENG
 typedef enum {
-    ESP_SHA256_STATE_INIT,
-    ESP_SHA256_STATE_IN_PROCESS
-} esp_sha256_state;
+    ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */
+    ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */
+    ESP_MBEDTLS_SHA256_SOFTWARE, /* using software SHA */
+} esp_mbedtls_sha256_mode;
 
 /**
  * \brief          SHA-256 context structure
@@ -45,18 +46,11 @@ typedef struct {
     uint32_t total[2];          /*!< number of bytes processed  */
     uint32_t state[8];          /*!< intermediate digest state  */
     unsigned char buffer[64];   /*!< data block being processed */
-    int first_block;           /*!< if first then true, else false */
-    esp_sha_type mode;
-    esp_sha256_state sha_state;
-}
-mbedtls_sha256_context;
-
-#endif //CONFIG_IDF_TARGET_ESP32S3
-
-#if CONFIG_IDF_TARGET_ESP32S2
-
-#include "esp32s2/sha.h"
+    int is224;                  /*!< 0 => SHA-256, else SHA-224 */
+    esp_mbedtls_sha256_mode mode;
+} mbedtls_sha256_context;
 
+#elif SOC_SHA_SUPPORT_DMA
 typedef enum {
     ESP_SHA256_STATE_INIT,
     ESP_SHA256_STATE_IN_PROCESS
@@ -72,32 +66,9 @@ typedef struct {
     int first_block;           /*!< if first then true, else false */
     esp_sha_type mode;
     esp_sha256_state sha_state;
-}
-mbedtls_sha256_context;
-
-#endif //CONFIG_IDF_TARGET_ESP32S2
-
-#if CONFIG_IDF_TARGET_ESP32
-
-typedef enum {
-    ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */
-    ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */
-    ESP_MBEDTLS_SHA256_SOFTWARE, /* using software SHA */
-} esp_mbedtls_sha256_mode;
-
-/**
- * \brief          SHA-256 context structure
- */
-typedef struct {
-    uint32_t total[2];          /*!< number of bytes processed  */
-    uint32_t state[8];          /*!< intermediate digest state  */
-    unsigned char buffer[64];   /*!< data block being processed */
-    int is224;                  /*!< 0 => SHA-256, else SHA-224 */
-    esp_mbedtls_sha256_mode mode;
-}
-mbedtls_sha256_context;
+} mbedtls_sha256_context;
 
-#endif //CONFIG_IDF_TARGET_ESP32
+#endif
 
 #endif
 

+ 13 - 49
components/mbedtls/port/include/sha512_alt.h

@@ -23,20 +23,23 @@
 #ifndef _SHA512_ALT_H_
 #define _SHA512_ALT_H_
 
+#if defined(MBEDTLS_SHA512_ALT)
+
+#include "hal/sha_types.h"
+#include "soc/sha_caps.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if defined(MBEDTLS_SHA512_ALT)
 
-#if CONFIG_IDF_TARGET_ESP32S3
-#include "esp32s3/sha.h"
+#if SOC_SHA_SUPPORT_PARALLEL_ENG
 
 typedef enum {
-    ESP_SHA512_STATE_INIT,
-    ESP_SHA512_STATE_IN_PROCESS
-} esp_sha512_state;
+    ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */
+    ESP_MBEDTLS_SHA512_HARDWARE, /* using hardware SHA engine */
+    ESP_MBEDTLS_SHA512_SOFTWARE, /* using software SHA */
+} esp_mbedtls_sha512_mode;
 
 /**
  * \brief          SHA-512 context structure
@@ -45,29 +48,11 @@ typedef struct {
     uint64_t total[2];          /*!< number of bytes processed  */
     uint64_t state[8];          /*!< intermediate digest state  */
     unsigned char buffer[128];  /*!< data block being processed */
-    int first_block;
-    esp_sha_type mode;
-    uint32_t t_val;             /*!< t_val for 512/t mode */
-    esp_sha512_state sha_state;
+    int is384;                  /*!< 0 => SHA-512, else SHA-384 */
+    esp_mbedtls_sha512_mode mode;
 } mbedtls_sha512_context;
 
-/**
- * @brief Sets the specfic algorithm for SHA512
- *
- * @param ctx The mbedtls sha512 context
- *
- * @param type The mode, used for setting SHA2_512224 and SHA2_512256:
- *
- */
-void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type);
-
-/* For SHA512/t mode the intial hash value will depend on t */
-void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val);
-
-#endif //CONFIG_IDF_TARGET_ESP32S3
-
-#if CONFIG_IDF_TARGET_ESP32S2
-#include "esp32s2/sha.h"
+#elif SOC_SHA_SUPPORT_DMA
 
 typedef enum {
     ESP_SHA512_STATE_INIT,
@@ -100,29 +85,8 @@ void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type);
 /* For SHA512/t mode the intial hash value will depend on t */
 void esp_sha512_set_t( mbedtls_sha512_context *ctx, uint16_t t_val);
 
-#endif //CONFIG_IDF_TARGET_ESP32S2
-
-#if CONFIG_IDF_TARGET_ESP32
-
-typedef enum {
-    ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */
-    ESP_MBEDTLS_SHA512_HARDWARE, /* using hardware SHA engine */
-    ESP_MBEDTLS_SHA512_SOFTWARE, /* using software SHA */
-} esp_mbedtls_sha512_mode;
-
-/**
- * \brief          SHA-512 context structure
- */
-typedef struct {
-    uint64_t total[2];          /*!< number of bytes processed  */
-    uint64_t state[8];          /*!< intermediate digest state  */
-    unsigned char buffer[128];  /*!< data block being processed */
-    int is384;                  /*!< 0 => SHA-512, else SHA-384 */
-    esp_mbedtls_sha512_mode mode;
-}
-mbedtls_sha512_context;
 
-#endif //CONFIG_IDF_TARGET_ESP32
+#endif
 
 #endif
 

+ 7 - 6
components/mbedtls/port/esp32s3/esp_sha1.c → components/mbedtls/port/sha/dma/esp_sha1.c

@@ -1,7 +1,5 @@
 /*
- *  SHA-1 implementation with hardware ESP32 support added.
- *  Uses mbedTLS software implementation for failover when concurrent
- *  SHA operations are in use.
+ *  SHA-1 implementation with hardware ESP support added.
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
@@ -47,12 +45,15 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-#include "esp32s3/sha.h"
+#include "sha/sha_dma.h"
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n )
 {
-    volatile unsigned char *p = (unsigned char *)v; while ( n-- ) *p++ = 0;
+    volatile unsigned char *p = (unsigned char *)v;
+    while ( n-- ) {
+        *p++ = 0;
+    }
 }
 
 /*
@@ -167,9 +168,9 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
     if ( len || local_len) {
 
         esp_sha_acquire_hardware();
-
         if (ctx->sha_state == ESP_SHA1_STATE_INIT) {
             ctx->first_block = true;
+
             ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
         } else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
             ctx->first_block = false;

+ 6 - 5
components/mbedtls/port/esp32s3/esp_sha256.c → components/mbedtls/port/sha/dma/esp_sha256.c

@@ -1,7 +1,5 @@
 /*
- *  SHA-256 implementation with hardware ESP32 support added.
- *  Uses mbedTLS software implementation for failover when concurrent
- *  SHA operations are in use.
+ *  SHA-256 implementation with hardware ESP support added.
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
@@ -48,12 +46,15 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-#include "esp32s3/sha.h"
+#include "sha/sha_dma.h"
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n )
 {
-    volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
+    volatile unsigned char *p = v;
+    while ( n-- ) {
+        *p++ = 0;
+    }
 }
 
 /*

+ 6 - 5
components/mbedtls/port/esp32s2/esp_sha512.c → components/mbedtls/port/sha/dma/esp_sha512.c

@@ -1,7 +1,5 @@
 /*
- *  SHA-512 implementation with hardware ESP32 support added.
- *  Uses mbedTLS software implementation for failover when concurrent
- *  SHA operations are in use.
+ *  SHA-512 implementation with hardware ESP support added.
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  *  Additions Copyright (C) 2016-2020, Espressif Systems (Shanghai) PTE LTD
@@ -54,12 +52,15 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-#include "esp32s2/sha.h"
+#include "sha/sha_dma.h"
 
 /* Implementation that should never be optimized out by the compiler */
 static void mbedtls_zeroize( void *v, size_t n )
 {
-    volatile unsigned char *p = v; while ( n-- ) *p++ = 0;
+    volatile unsigned char *p = v;
+    while ( n-- ) {
+        *p++ = 0;
+    }
 }
 
 /*

+ 60 - 147
components/mbedtls/port/esp32s2/sha.c → components/mbedtls/port/sha/dma/sha.c

@@ -1,5 +1,5 @@
 /*
- *  ESP32 hardware accelerated SHA1/256/512 implementation
+ *  ESP hardware accelerated SHA1/256/512 implementation
  *  based on mbedTLS FIPS-197 compliant version.
  *
  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
@@ -31,11 +31,8 @@
 
 #include "esp_log.h"
 #include "esp_crypto_lock.h"
-#include "esp32s2/rom/cache.h"
-#include "esp32s2/rom/lldesc.h"
-#include "soc/crypto_dma_reg.h"
+#include "soc/lldesc.h"
 #include "soc/dport_reg.h"
-#include "soc/hwcrypto_reg.h"
 #include "soc/cache_memory.h"
 #include "soc/periph_defs.h"
 
@@ -45,19 +42,39 @@
 #include "driver/periph_ctrl.h"
 #include "sys/param.h"
 
-#include "esp32s2/sha.h"
+#include "sha/sha_dma.h"
+#include "hal/sha_hal.h"
+#include "soc/sha_caps.h"
 
-/* Max amount of bytes in a single DMA operation is 4095,
-   for SHA this means that the biggest safe amount of bytes is
-   31 blocks of 128 bytes = 3968
-*/
-#define SHA_DMA_MAX_BYTES 3968
+#if CONFIG_IDF_TARGET_ESP32S2
+#include "esp32s2/rom/cache.h"
+#elif CONFIG_IDF_TARGET_ESP32S3
+#include "esp32s3/rom/cache.h"
+#endif
 
-/* The longest length of a single block is for SHA512 = 128 byte */
-#define SHA_MAX_BLK_LEN 128
+#if SOC_SHA_GENERAL_DMA
+#define SHA_LOCK() esp_crypto_sha_lock_acquire()
+#define SHA_RELEASE() esp_crypto_sha_lock_release()
+#elif SOC_SHA_CRYPTO_DMA
+#define SHA_LOCK() esp_crypto_dma_lock_acquire()
+#define SHA_RELEASE() esp_crypto_dma_lock_release()
+#else
+#define SHA_LOCK() ()
+#endif
 
 const static char *TAG = "esp-sha";
 
+
+void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
+{
+    sha_hal_write_digest(sha_type, digest_state);
+}
+
+void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
+{
+    sha_hal_read_digest(sha_type, digest_state);
+}
+
 /* Return block size (in bytes) for a given SHA type */
 inline static size_t block_length(esp_sha_type type)
 {
@@ -77,83 +94,36 @@ inline static size_t block_length(esp_sha_type type)
     }
 }
 
-/* Return state size (in bytes) for a given SHA type */
-inline static size_t state_length(esp_sha_type type)
-{
-    switch (type) {
-    case SHA1:
-        return 160 / 8;
-    case SHA2_224:
-    case SHA2_256:
-        return 256 / 8;
-    case SHA2_384:
-    case SHA2_512:
-    case SHA2_512224:
-    case SHA2_512256:
-    case SHA2_512T:
-        return 512 / 8;
-    default:
-        return 0;
-    }
-}
 
 /* Enable SHA peripheral and then lock it */
 void esp_sha_acquire_hardware()
 {
-    esp_crypto_dma_lock_acquire();
+    SHA_LOCK(); /* Released when releasing hw with esp_sha_release_hardware() */
 
     /* Enable SHA and DMA hardware */
+#if SOC_SHA_CRYPTO_DMA
     periph_module_enable(PERIPH_SHA_DMA_MODULE);
-
-    /* DMA for SHA */
-    REG_WRITE(CRYPTO_DMA_AES_SHA_SELECT_REG, 1);
+#elif SOC_SHA_GENERAL_DMA
+    periph_module_enable(PERIPH_SHA_MODULE);
+    periph_module_enable(PERIPH_GDMA_MODULE);
+#endif
 }
 
 /* Disable SHA peripheral block and then release it */
 void esp_sha_release_hardware()
 {
     /* Disable SHA and DMA hardware */
+#if SOC_SHA_CRYPTO_DMA
     periph_module_disable(PERIPH_SHA_DMA_MODULE);
+#elif SOC_SHA_GENERAL_DMA
+    periph_module_disable(PERIPH_SHA_MODULE);
+    periph_module_disable(PERIPH_GDMA_MODULE);
+#endif
 
-    esp_crypto_dma_lock_release();
-}
-
-/* Busy wait until SHA is idle */
-static void esp_sha_wait_idle(void)
-{
-    while (DPORT_REG_READ(SHA_BUSY_REG) != 0) {
-    }
-}
-
-void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
-{
-    uint32_t *digest_state_words = (uint32_t *)digest_state;
-    uint32_t *reg_addr_buf = (uint32_t *)(SHA_H_BASE);
-
-    for (int i = 0; i < state_length(sha_type) / 4; i++) {
-        REG_WRITE(&reg_addr_buf[i], digest_state_words[i]);
-    }
-}
-
-/* Read the SHA digest from hardware */
-void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
-{
-    uint32_t *digest_state_words = (uint32_t *)digest_state;
-    int word_len = state_length(sha_type) / 4;
-
-    esp_dport_access_read_buffer(digest_state_words, SHA_H_BASE, word_len);
-
-    /* Fault injection check: verify SHA engine actually ran,
-       state is not all zeroes.
-    */
-    for (int i = 0; i < word_len; i++) {
-        if (digest_state_words[i] != 0) {
-            return;
-        }
-    }
-    abort(); // SHA peripheral returned all zero state, probably due to fault injection
+    SHA_RELEASE();
 }
 
+#if SOC_SHA_SUPPORT_SHA512_T
 /* The initial hash value for SHA512/t is generated according to the
    algorithm described in the TRM, chapter SHA-Accelerator
 */
@@ -188,72 +158,41 @@ int esp_sha_512_t_init_hash(uint16_t t)
         return -1;
     }
 
-    REG_WRITE(SHA_T_LENGTH_REG, t_len);
-    REG_WRITE(SHA_T_STRING_REG, t_string);
-    REG_WRITE(SHA_MODE_REG, SHA2_512T);
-    REG_WRITE(SHA_START_REG, 1);
-
-    esp_sha_wait_idle();
+    sha_hal_sha512_init_hash(t_string, t_len);
 
     return 0;
 }
 
-static void esp_sha_fill_text_block(esp_sha_type sha_type, const void *input)
-{
-    uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
-    uint32_t *data_words = NULL;
+#endif //SOC_SHA_SUPPORT_SHA512_T
 
-    /* Fill the data block */
-    data_words = (uint32_t *)(input);
-    for (int i = 0; i < block_length(sha_type) / 4; i++) {
-        reg_addr_buf[i] = (data_words[i]);
-    }
-    asm volatile ("memw");
-}
-
-/* Hash a single SHA block */
-static void esp_sha_block(esp_sha_type sha_type, const void *input, bool is_first_block)
-{
-    esp_sha_fill_text_block(sha_type, input);
-
-    esp_sha_wait_idle();
-    /* Start hashing */
-    if (is_first_block) {
-        REG_WRITE(SHA_START_REG, 1);
-    } else {
-        REG_WRITE(SHA_CONTINUE_REG, 1);
-    }
-}
 
 /* Hash the input block by block, using non-DMA mode */
 static void esp_sha_block_mode(esp_sha_type sha_type, const uint8_t *input, uint32_t ilen,
-                                const uint8_t *buf, uint32_t buf_len, bool is_first_block)
+                               const uint8_t *buf, uint32_t buf_len, bool is_first_block)
 {
     size_t blk_len = 0;
+    size_t blk_word_len = 0;
     int num_block = 0;
 
     blk_len = block_length(sha_type);
-
-    REG_WRITE(SHA_MODE_REG, sha_type);
+    blk_word_len =  blk_len / 4;
     num_block = ilen / blk_len;
 
     if (buf_len != 0) {
-        esp_sha_block(sha_type, buf, is_first_block);
+        sha_hal_hash_block(sha_type, buf, blk_word_len, is_first_block);
         is_first_block = false;
     }
 
     for (int i = 0; i < num_block; i++) {
-        esp_sha_block(sha_type, input + blk_len*i, is_first_block);
+        sha_hal_hash_block(sha_type, input + blk_len * i, blk_word_len, is_first_block);
         is_first_block = false;
     }
-
-    esp_sha_wait_idle();
 }
 
 
 
 static int esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
-                                const void *buf, uint32_t buf_len, bool is_first_block);
+                               const void *buf, uint32_t buf_len, bool is_first_block);
 
 /* Performs SHA on multiple blocks at a time using DMA
    splits up into smaller operations for inputs that exceed a single DMA list
@@ -263,20 +202,20 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
 {
     int ret = 0;
     unsigned char *dma_cap_buf = NULL;
-    int dma_op_num = ( ilen / (SHA_DMA_MAX_BYTES + 1) ) + 1;
+    int dma_op_num = ( ilen / (SOC_SHA_DMA_MAX_BUFFER_SIZE + 1) ) + 1;
 
     if (buf_len > block_length(sha_type)) {
         ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block");
         return -1;
     }
 
-    /* DMA cannot access memory in the iCache range, hash block by block instead of using DMA */
+    /* DMA cannot access memory in flash, hash block by block instead of using DMA */
     if (!esp_ptr_dma_ext_capable(input) && !esp_ptr_dma_capable(input) && (ilen != 0)) {
         esp_sha_block_mode(sha_type, input, ilen, buf, buf_len, is_first_block);
         return 0;
     }
 
-#if (CONFIG_ESP32S2_SPIRAM_SUPPORT)
+#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
     if (esp_ptr_external_ram(input)) {
         Cache_WriteBack_Addr((uint32_t)input, ilen);
     }
@@ -303,7 +242,7 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
        which is max 3968/64 + 64/64 = 63 blocks */
     for (int i = 0; i < dma_op_num; i++) {
 
-        int dma_chunk_len = MIN(ilen, SHA_DMA_MAX_BYTES);
+        int dma_chunk_len = MIN(ilen, SOC_SHA_DMA_MAX_BUFFER_SIZE);
 
         ret = esp_sha_dma_process(sha_type, input, dma_chunk_len, buf, buf_len, is_first_block);
 
@@ -324,34 +263,16 @@ cleanup:
     return ret;
 }
 
-static void esp_sha_dma_init(lldesc_t *input)
-{
-    /* Reset DMA */
-    SET_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
-    CLEAR_PERI_REG_MASK(CRYPTO_DMA_CONF0_REG, CONF0_REG_AHBM_RST | CONF0_REG_OUT_RST | CONF0_REG_AHBM_FIFO_RST);
-
-    /* Set descriptors */
-    CLEAR_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_ADDR);
-    SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, ((uint32_t)(input))&OUT_LINK_REG_OUTLINK_ADDR);
-    /* Start transfer */
-    SET_PERI_REG_MASK(CRYPTO_DMA_OUT_LINK_REG, OUT_LINK_REG_OUTLINK_START);
-}
 
 /* Performs SHA on multiple blocks at a time */
 static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, uint32_t ilen,
-                                      const void *buf, uint32_t buf_len, bool is_first_block)
+                                     const void *buf, uint32_t buf_len, bool is_first_block)
 {
-    size_t blk_len = 0;
     int ret = 0;
     lldesc_t dma_descr_input = {};
     lldesc_t dma_descr_buf = {};
     lldesc_t *dma_descr_head;
-
-    blk_len = block_length(sha_type);
-
-    REG_WRITE(SHA_MODE_REG, sha_type);
-    REG_WRITE(SHA_BLOCK_NUM_REG, ((ilen + buf_len) / blk_len));
-
+    size_t num_blks = (ilen + buf_len) / block_length(sha_type);
 
     /* DMA descriptor for Memory to DMA-SHA transfer */
     if (ilen) {
@@ -359,7 +280,7 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u
         dma_descr_input.size = ilen;
         dma_descr_input.owner = 1;
         dma_descr_input.eof = 1;
-        dma_descr_input.buf = input;
+        dma_descr_input.buf = (uint8_t *)input;
         dma_descr_head = &dma_descr_input;
     }
     /* Check after input to overide head if there is any buf*/
@@ -368,7 +289,7 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u
         dma_descr_buf.size = buf_len;
         dma_descr_buf.owner = 1;
         dma_descr_buf.eof = 1;
-        dma_descr_buf.buf = buf;
+        dma_descr_buf.buf = (uint8_t *)buf;
         dma_descr_head = &dma_descr_buf;
     }
 
@@ -378,16 +299,8 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u
         dma_descr_buf.empty = (uint32_t)(&dma_descr_input);
     }
 
-    esp_sha_dma_init(dma_descr_head);
-
-    /* Start hashing */
-    if (is_first_block) {
-        REG_WRITE(SHA_DMA_START_REG, 1);
-    } else {
-        REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
-    }
+    sha_hal_hash_dma(sha_type, dma_descr_head, num_blks, is_first_block);
 
-    esp_sha_wait_idle();
 
     return ret;
 }

+ 30 - 15
components/mbedtls/port/esp_sha.c → components/mbedtls/port/sha/esp_sha.c

@@ -15,26 +15,29 @@
 #include <string.h>
 #include <stdio.h>
 #include <assert.h>
-#if CONFIG_IDF_TARGET_ESP32
-#include "esp32/sha.h"
-#elif CONFIG_IDF_TARGET_ESP32S2
-#include "esp32s2/sha.h"
-#elif CONFIG_IDF_TARGET_ESP32S3
-#include "esp32s3/sha.h"
-#endif
+#include "hal/sha_types.h"
+#include "soc/sha_caps.h"
+#include "esp_log.h"
 
 #include <mbedtls/sha1.h>
 #include <mbedtls/sha256.h>
 #include <mbedtls/sha512.h>
 
+#if SOC_SHA_SUPPORT_PARALLEL_ENG
+#include "sha/sha_parallel_engine.h"
+#elif SOC_SHA_SUPPORT_DMA
+#include "sha/sha_dma.h"
+#endif
+
+static const char *TAG = "esp_sha";
 
 void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
 {
     int ret;
     assert(input != NULL && output != NULL);
 
+#if SOC_SHA_SUPPORT_SHA1
     if (sha_type == SHA1) {
-
         mbedtls_sha1_context *ctx1 = (mbedtls_sha1_context *)malloc(sizeof(mbedtls_sha1_context));
         assert(ctx1 != NULL);
         mbedtls_sha1_starts_ret(ctx1);
@@ -44,9 +47,12 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
         assert(ret == 0);
         mbedtls_sha1_free(ctx1);
         free(ctx1);
+        return;
+    }
+#endif //SOC_SHA_SUPPORT_SHA1
 
-    } else if (sha_type == SHA2_256) {
-
+#if SOC_SHA_SUPPORT_SHA256
+    if (sha_type == SHA2_256) {
         mbedtls_sha256_context *ctx256 = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context));
         assert(ctx256 != NULL);
         mbedtls_sha256_starts_ret(ctx256, 0);
@@ -56,9 +62,12 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
         assert(ret == 0);
         mbedtls_sha256_free(ctx256);
         free(ctx256);
+        return;
+    }
+#endif //SOC_SHA_SUPPORT_SHA256
 
-    } else if (sha_type == SHA2_384) {
-
+#if SOC_SHA_SUPPORT_SHA384
+    if (sha_type == SHA2_384) {
         mbedtls_sha512_context *ctx384 = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context));
         assert(ctx384 != NULL);
         mbedtls_sha512_starts_ret(ctx384, 1);
@@ -68,9 +77,12 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
         assert(ret == 0);
         mbedtls_sha512_free(ctx384);
         free(ctx384);
+        return;
+    }
+#endif //SOC_SHA_SUPPORT_SHA384
 
-    } else if (sha_type == SHA2_512) {
-
+#if SOC_SHA_SUPPORT_SHA512
+    if (sha_type == SHA2_512) {
         mbedtls_sha512_context *ctx512 = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context));
         assert(ctx512 != NULL);
         mbedtls_sha512_starts_ret(ctx512, 0);
@@ -80,7 +92,10 @@ void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, uns
         assert(ret == 0);
         mbedtls_sha512_free(ctx512);
         free(ctx512);
-
+        return;
     }
+#endif //SOC_SHA_SUPPORT_SHA512
 
+    ESP_LOGE(TAG, "SHA type %d not supported", sha_type);
+    abort();
 }

+ 20 - 15
components/mbedtls/port/esp32/esp_sha1.c → components/mbedtls/port/sha/parallel_engine/esp_sha1.c

@@ -47,11 +47,15 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-#include "esp32/sha.h"
+#include "sha/sha_parallel_engine.h"
 
 /* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
+static void mbedtls_zeroize( void *v, size_t n )
+{
+    volatile unsigned char *p = (unsigned char *)v;
+    while ( n-- ) {
+        *p++ = 0;
+    }
 }
 
 /*
@@ -84,8 +88,9 @@ void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
 
 void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
 {
-    if( ctx == NULL )
+    if ( ctx == NULL ) {
         return;
+    }
 
     if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
         esp_sha_unlock_engine(SHA1);
@@ -335,8 +340,9 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
     size_t fill;
     uint32_t left;
 
-    if( ilen == 0 )
+    if ( ilen == 0 ) {
         return 0;
+    }
 
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
@@ -344,11 +350,11 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
     ctx->total[0] += (uint32_t) ilen;
     ctx->total[0] &= 0xFFFFFFFF;
 
-    if( ctx->total[0] < (uint32_t) ilen )
+    if ( ctx->total[0] < (uint32_t) ilen ) {
         ctx->total[1]++;
+    }
 
-    if( left && ilen >= fill )
-    {
+    if ( left && ilen >= fill ) {
         memcpy( (void *) (ctx->buffer + left), input, fill );
 
         if ( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) {
@@ -360,8 +366,7 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
         left = 0;
     }
 
-    while( ilen >= 64 )
-    {
+    while ( ilen >= 64 ) {
         if ( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) {
             return ret;
         }
@@ -370,8 +375,9 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *inp
         ilen  -= 64;
     }
 
-    if( ilen > 0 )
+    if ( ilen > 0 ) {
         memcpy( (void *) (ctx->buffer + left), input, ilen );
+    }
 
     return 0;
 }
@@ -385,9 +391,8 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
 }
 #endif
 
-static const unsigned char sha1_padding[64] =
-{
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+static const unsigned char sha1_padding[64] = {
+    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -404,7 +409,7 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20]
     unsigned char msglen[8];
 
     high = ( ctx->total[0] >> 29 )
-         | ( ctx->total[1] <<  3 );
+           | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
     PUT_UINT32_BE( high, msglen, 0 );

+ 54 - 51
components/mbedtls/port/esp32/esp_sha256.c → components/mbedtls/port/sha/parallel_engine/esp_sha256.c

@@ -48,11 +48,15 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-#include "esp32/sha.h"
+#include "sha/sha_parallel_engine.h"
 
 /* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+static void mbedtls_zeroize( void *v, size_t n )
+{
+    volatile unsigned char *p = v;
+    while ( n-- ) {
+        *p++ = 0;
+    }
 }
 
 /*
@@ -85,8 +89,9 @@ void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
 
 void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
 {
-    if( ctx == NULL )
+    if ( ctx == NULL ) {
         return;
+    }
 
     if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
         esp_sha_unlock_engine(SHA2_256);
@@ -116,8 +121,7 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
     ctx->total[0] = 0;
     ctx->total[1] = 0;
 
-    if( is224 == 0 )
-    {
+    if ( is224 == 0 ) {
         /* SHA-256 */
         ctx->state[0] = 0x6A09E667;
         ctx->state[1] = 0xBB67AE85;
@@ -127,9 +131,7 @@ int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
         ctx->state[5] = 0x9B05688C;
         ctx->state[6] = 0x1F83D9AB;
         ctx->state[7] = 0x5BE0CD19;
-    }
-    else
-    {
+    } else {
         /* SHA-224 */
         ctx->state[0] = 0xC1059ED8;
         ctx->state[1] = 0x367CD507;
@@ -157,8 +159,7 @@ void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
 }
 #endif
 
-static const uint32_t K[] =
-{
+static const uint32_t K[] = {
     0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
     0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
     0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
@@ -241,16 +242,17 @@ static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const
     uint32_t A[8];
     unsigned int i;
 
-    for( i = 0; i < 8; i++ )
+    for ( i = 0; i < 8; i++ ) {
         A[i] = ctx->state[i];
+    }
 
 #if defined(MBEDTLS_SHA256_SMALLER)
-    for( i = 0; i < 64; i++ )
-    {
-        if( i < 16 )
+    for ( i = 0; i < 64; i++ ) {
+        if ( i < 16 ) {
             GET_UINT32_BE( W[i], data, 4 * i );
-        else
+        } else {
             R( i );
+        }
 
         P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
 
@@ -258,50 +260,51 @@ static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const
         A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
     }
 #else /* MBEDTLS_SHA256_SMALLER */
-    for( i = 0; i < 16; i++ )
+    for ( i = 0; i < 16; i++ ) {
         GET_UINT32_BE( W[i], data, 4 * i );
+    }
 
-    for( i = 0; i < 16; i += 8 )
-    {
-        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
-        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
-        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
-        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
-        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
-        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
-        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
-        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
+    for ( i = 0; i < 16; i += 8 ) {
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i + 0], K[i + 0] );
+        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i + 1], K[i + 1] );
+        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i + 2], K[i + 2] );
+        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i + 3], K[i + 3] );
+        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i + 4], K[i + 4] );
+        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i + 5], K[i + 5] );
+        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i + 6], K[i + 6] );
+        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i + 7], K[i + 7] );
     }
 
-    for( i = 16; i < 64; i += 8 )
-    {
-        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
-        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
-        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
-        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
-        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
-        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
-        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
-        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
+    for ( i = 16; i < 64; i += 8 ) {
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i + 0), K[i + 0] );
+        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i + 1), K[i + 1] );
+        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i + 2), K[i + 2] );
+        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i + 3), K[i + 3] );
+        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i + 4), K[i + 4] );
+        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i + 5), K[i + 5] );
+        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i + 6), K[i + 6] );
+        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i + 7), K[i + 7] );
     }
 #endif /* MBEDTLS_SHA256_SMALLER */
 
-    for( i = 0; i < 8; i++ )
+    for ( i = 0; i < 8; i++ ) {
         ctx->state[i] += A[i];
+    }
 }
 
 /*
  * SHA-256 process buffer
  */
 int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input,
-                    size_t ilen )
+                               size_t ilen )
 {
     int ret;
     size_t fill;
     uint32_t left;
 
-    if( ilen == 0 )
+    if ( ilen == 0 ) {
         return 0;
+    }
 
     left = ctx->total[0] & 0x3F;
     fill = 64 - left;
@@ -309,11 +312,11 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char
     ctx->total[0] += (uint32_t) ilen;
     ctx->total[0] &= 0xFFFFFFFF;
 
-    if( ctx->total[0] < (uint32_t) ilen )
+    if ( ctx->total[0] < (uint32_t) ilen ) {
         ctx->total[1]++;
+    }
 
-    if( left && ilen >= fill )
-    {
+    if ( left && ilen >= fill ) {
         memcpy( (void *) (ctx->buffer + left), input, fill );
 
         if ( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) {
@@ -325,8 +328,7 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char
         left = 0;
     }
 
-    while( ilen >= 64 )
-    {
+    while ( ilen >= 64 ) {
         if ( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 ) {
             return ret;
         }
@@ -335,8 +337,9 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char
         ilen  -= 64;
     }
 
-    if( ilen > 0 )
+    if ( ilen > 0 ) {
         memcpy( (void *) (ctx->buffer + left), input, ilen );
+    }
 
     return 0;
 }
@@ -350,9 +353,8 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
 }
 #endif
 
-static const unsigned char sha256_padding[64] =
-{
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+static const unsigned char sha256_padding[64] = {
+    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -369,7 +371,7 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output
     unsigned char msglen[8];
 
     high = ( ctx->total[0] >> 29 )
-         | ( ctx->total[1] <<  3 );
+           | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
     PUT_UINT32_BE( high, msglen, 0 );
@@ -399,8 +401,9 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output
     PUT_UINT32_BE( ctx->state[5], output, 20 );
     PUT_UINT32_BE( ctx->state[6], output, 24 );
 
-    if( ctx->is224 == 0 )
+    if ( ctx->is224 == 0 ) {
         PUT_UINT32_BE( ctx->state[7], output, 28 );
+    }
 
 out:
     if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {

+ 31 - 35
components/mbedtls/port/esp32/esp_sha512.c → components/mbedtls/port/sha/parallel_engine/esp_sha512.c

@@ -38,9 +38,9 @@
 #include "mbedtls/sha512.h"
 
 #if defined(_MSC_VER) || defined(__WATCOMC__)
-  #define UL64(x) x##ui64
+#define UL64(x) x##ui64
 #else
-  #define UL64(x) x##ULL
+#define UL64(x) x##ULL
 #endif
 
 #include <string.h>
@@ -54,7 +54,7 @@
 #endif /* MBEDTLS_PLATFORM_C */
 #endif /* MBEDTLS_SELF_TEST */
 
-#include "esp32/sha.h"
+#include "sha/sha_parallel_engine.h"
 
 inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx)
 {
@@ -62,8 +62,12 @@ inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx)
 }
 
 /* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
-    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+static void mbedtls_zeroize( void *v, size_t n )
+{
+    volatile unsigned char *p = v;
+    while ( n-- ) {
+        *p++ = 0;
+    }
 }
 
 /*
@@ -104,8 +108,9 @@ void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
 
 void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
 {
-    if( ctx == NULL )
+    if ( ctx == NULL ) {
         return;
+    }
 
     if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
         esp_sha_unlock_engine(sha_type(ctx));
@@ -140,8 +145,7 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
     ctx->total[0] = 0;
     ctx->total[1] = 0;
 
-    if( is384 == 0 )
-    {
+    if ( is384 == 0 ) {
         /* SHA-512 */
         ctx->state[0] = UL64(0x6A09E667F3BCC908);
         ctx->state[1] = UL64(0xBB67AE8584CAA73B);
@@ -151,9 +155,7 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
         ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
         ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
         ctx->state[7] = UL64(0x5BE0CD19137E2179);
-    }
-    else
-    {
+    } else {
         /* SHA-384 */
         ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
         ctx->state[1] = UL64(0x629A292A367CD507);
@@ -185,8 +187,7 @@ void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
 /*
  * Round constants
  */
-static const uint64_t K[80] =
-{
+static const uint64_t K[80] = {
     UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
     UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
     UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
@@ -288,13 +289,11 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const
     d += temp1; h = temp1 + temp2;              \
 }
 
-    for( i = 0; i < 16; i++ )
-    {
+    for ( i = 0; i < 16; i++ ) {
         GET_UINT64_BE( W[i], data, i << 3 );
     }
 
-    for( ; i < 80; i++ )
-    {
+    for ( ; i < 80; i++ ) {
         W[i] = S1(W[i -  2]) + W[i -  7] +
                S0(W[i - 15]) + W[i - 16];
     }
@@ -309,8 +308,7 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const
     H = ctx->state[7];
     i = 0;
 
-    do
-    {
+    do {
         P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
         P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
         P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
@@ -319,8 +317,7 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const
         P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
         P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
         P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
-    }
-    while( i < 80 );
+    } while ( i < 80 );
 
     ctx->state[0] += A;
     ctx->state[1] += B;
@@ -336,25 +333,26 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const
  * SHA-512 process buffer
  */
 int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input,
-                    size_t ilen )
+                               size_t ilen )
 {
     int ret;
     size_t fill;
     unsigned int left;
 
-    if( ilen == 0 )
+    if ( ilen == 0 ) {
         return 0;
+    }
 
     left = (unsigned int) (ctx->total[0] & 0x7F);
     fill = 128 - left;
 
     ctx->total[0] += (uint64_t) ilen;
 
-    if( ctx->total[0] < (uint64_t) ilen )
+    if ( ctx->total[0] < (uint64_t) ilen ) {
         ctx->total[1]++;
+    }
 
-    if( left && ilen >= fill )
-    {
+    if ( left && ilen >= fill ) {
         memcpy( (void *) (ctx->buffer + left), input, fill );
         if ( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) {
             return ret;
@@ -365,8 +363,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char
         left = 0;
     }
 
-    while( ilen >= 128 )
-    {
+    while ( ilen >= 128 ) {
         if ( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 ) {
             return ret;
         }
@@ -375,8 +372,9 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char
         ilen  -= 128;
     }
 
-    if( ilen > 0 )
+    if ( ilen > 0 ) {
         memcpy( (void *) (ctx->buffer + left), input, ilen );
+    }
 
     return 0;
 }
@@ -391,9 +389,8 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
 #endif
 
 
-static const unsigned char sha512_padding[128] =
-{
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+static const unsigned char sha512_padding[128] = {
+    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -414,7 +411,7 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output
     unsigned char msglen[16];
 
     high = ( ctx->total[0] >> 61 )
-         | ( ctx->total[1] <<  3 );
+           | ( ctx->total[1] <<  3 );
     low  = ( ctx->total[0] <<  3 );
 
     PUT_UINT64_BE( high, msglen, 0 );
@@ -443,8 +440,7 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output
     PUT_UINT64_BE( ctx->state[4], output, 32 );
     PUT_UINT64_BE( ctx->state[5], output, 40 );
 
-    if( ctx->is384 == 0 )
-    {
+    if ( ctx->is384 == 0 ) {
         PUT_UINT64_BE( ctx->state[6], output, 48 );
         PUT_UINT64_BE( ctx->state[7], output, 56 );
     }

+ 24 - 113
components/mbedtls/port/esp32/sha.c → components/mbedtls/port/sha/parallel_engine/sha.c

@@ -33,27 +33,14 @@
 #include "freertos/FreeRTOS.h"
 #include "freertos/semphr.h"
 
-#include "esp32/sha.h"
+#include "hal/sha_hal.h"
+#include "hal/sha_types.h"
+#include "sha/sha_parallel_engine.h"
 #include "soc/hwcrypto_periph.h"
 #include "driver/periph_ctrl.h"
 
-inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type) {
-    return SHA_1_LOAD_REG + sha_type * 0x10;
-}
-
-inline static uint32_t SHA_BUSY_REG(esp_sha_type sha_type) {
-    return SHA_1_BUSY_REG + sha_type * 0x10;
-}
-
-inline static uint32_t SHA_START_REG(esp_sha_type sha_type) {
-    return SHA_1_START_REG + sha_type * 0x10;
-}
-
-inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type) {
-    return SHA_1_CONTINUE_REG + sha_type * 0x10;
-}
-
-/* Single spinlock for SHA engine memory block
+/*
+     Single spinlock for SHA engine memory block
 */
 static portMUX_TYPE memory_block_lock = portMUX_INITIALIZER_UNLOCKED;
 
@@ -76,45 +63,31 @@ static uint8_t engines_in_use;
 */
 static portMUX_TYPE engines_in_use_lock = portMUX_INITIALIZER_UNLOCKED;
 
-/* Index into the engine_states array */
-inline static size_t sha_engine_index(esp_sha_type type) {
-    switch(type) {
-    case SHA1:
-        return 0;
-    case SHA2_256:
-        return 1;
-    default:
-        return 2;
-    }
-}
-
-/* Return digest length (in bytes) for a given SHA type */
-inline static size_t sha_length(esp_sha_type type) {
-    switch(type) {
+/* Return block size (in words) for a given SHA type */
+inline static size_t block_length(esp_sha_type type)
+{
+    switch (type) {
     case SHA1:
-        return 20;
     case SHA2_256:
-        return 32;
+        return 64 / 4;
     case SHA2_384:
-        return 48;
     case SHA2_512:
-        return 64;
+        return 128 / 4;
     default:
         return 0;
     }
 }
 
-/* Return block size (in bytes) for a given SHA type */
-inline static size_t block_length(esp_sha_type type) {
-    switch(type) {
+/* Index into the engine_states array */
+inline static size_t sha_engine_index(esp_sha_type type)
+{
+    switch (type) {
     case SHA1:
+        return 0;
     case SHA2_256:
-        return 64;
-    case SHA2_384:
-    case SHA2_512:
-        return 128;
+        return 1;
     default:
-        return 0;
+        return 2;
     }
 }
 
@@ -211,23 +184,8 @@ void esp_sha_unlock_engine(esp_sha_type sha_type)
     xSemaphoreGive(engine_state);
 }
 
-void esp_sha_wait_idle(void)
-{
-    while(1) {
-        if(DPORT_REG_READ(SHA_1_BUSY_REG) == 0
-           && DPORT_REG_READ(SHA_256_BUSY_REG) == 0
-           && DPORT_REG_READ(SHA_384_BUSY_REG) == 0
-           && DPORT_REG_READ(SHA_512_BUSY_REG) == 0) {
-            break;
-        }
-    }
-}
-
 void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
 {
-    uint32_t *digest_state_words = NULL;
-    uint32_t *reg_addr_buf = NULL;
-    uint32_t word_len = sha_length(sha_type)/4;
 #ifndef NDEBUG
     {
         SemaphoreHandle_t engine_state = sha_get_engine_state(sha_type);
@@ -237,44 +195,17 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
 #endif
 
     // preemptively do this before entering the critical section, then re-check once in it
-    esp_sha_wait_idle();
+    sha_hal_wait_idle();
 
     esp_sha_lock_memory_block();
 
-    esp_sha_wait_idle();
-
-    DPORT_REG_WRITE(SHA_LOAD_REG(sha_type), 1);
-    while(DPORT_REG_READ(SHA_BUSY_REG(sha_type)) == 1) { }
-    digest_state_words = (uint32_t *)digest_state;
-    reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
-    if(sha_type == SHA2_384 || sha_type == SHA2_512) {
-        /* for these ciphers using 64-bit states, swap each pair of words */
-        DPORT_INTERRUPT_DISABLE(); // Disable interrupt only on current CPU.
-        for(int i = 0; i < word_len; i += 2) {
-            digest_state_words[i+1] = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i]);
-            digest_state_words[i]   = DPORT_SEQUENCE_REG_READ((uint32_t)&reg_addr_buf[i+1]);
-        }
-        DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level
-    } else {
-        esp_dport_access_read_buffer(digest_state_words, (uint32_t)&reg_addr_buf[0], word_len);
-    }
-    esp_sha_unlock_memory_block();
+    sha_hal_read_digest(sha_type, digest_state);
 
-    /* Fault injection check: verify SHA engine actually ran,
-       state is not all zeroes.
-    */
-    for (int i = 0; i < word_len; i++) {
-        if (digest_state_words[i] != 0) {
-            return;
-        }
-    }
-    abort(); // SHA peripheral returned all zero state, probably due to fault injection
+    esp_sha_unlock_memory_block();
 }
 
-void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
+void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool first_block)
 {
-    uint32_t *reg_addr_buf = NULL;
-    uint32_t *data_words = NULL;
 #ifndef NDEBUG
     {
         SemaphoreHandle_t engine_state = sha_get_engine_state(sha_type);
@@ -284,30 +215,10 @@ void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_
 #endif
 
     // preemptively do this before entering the critical section, then re-check once in it
-    esp_sha_wait_idle();
-
+    sha_hal_wait_idle();
     esp_sha_lock_memory_block();
 
-    esp_sha_wait_idle();
-
-    /* Fill the data block */
-    reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
-    data_words = (uint32_t *)data_block;
-    for (int i = 0; i < block_length(sha_type) / 4; i++) {
-        reg_addr_buf[i] = __builtin_bswap32(data_words[i]);
-    }
-    asm volatile ("memw");
-
-    if(is_first_block) {
-        DPORT_REG_WRITE(SHA_START_REG(sha_type), 1);
-    } else {
-        DPORT_REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
-    }
+    sha_hal_hash_block(sha_type, data_block, block_length(sha_type), first_block);
 
     esp_sha_unlock_memory_block();
-
-    /* Note: deliberately not waiting for this operation to complete,
-       as a performance tweak - delay waiting until the next time we need the SHA
-       unit, instead.
-    */
 }

+ 91 - 0
components/soc/include/hal/sha_hal.h

@@ -0,0 +1,91 @@
+// Copyright 2015-2019 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.
+
+/*******************************************************************************
+ * NOTICE
+ * The hal is not public api, don't use in application code.
+ * See readme.md in soc/include/hal/readme.md
+ ******************************************************************************/
+
+#pragma once
+
+#include <stddef.h>
+#include <stdbool.h>
+#include "soc/sha_caps.h"
+#include "soc/lldesc.h"
+#include "hal/sha_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Hashes a single message block
+ *
+ * @param sha_type          SHA algorithm to hash with
+ * @param data_block        Input message to be hashed
+ * @param block_word_len    Length of the input message
+ * @param first_block       Is this the first block in a message or a continuation?
+ */
+void sha_hal_hash_block(esp_sha_type sha_type, const void *data_block, size_t block_word_len, bool first_block);
+
+/**
+ * @brief Polls and waits until the SHA engine is idle
+ *
+ */
+void sha_hal_wait_idle(void);
+
+/**
+ * @brief Reads the current message digest from the SHA engine
+ *
+ * @param sha_type SHA algorithm used
+ * @param digest_state Output buffer to which to read message digest to
+ */
+void sha_hal_read_digest(esp_sha_type sha_type, void *digest_state);
+
+#if SOC_SHA_SUPPORT_RESUME
+/**
+ * @brief Writes 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
+ */
+void sha_hal_write_digest(esp_sha_type sha_type, void *digest_state);
+#endif
+
+#if SOC_SHA_SUPPORT_DMA
+/**
+ * @brief Hashes a number of message blocks using DMA
+ *
+ * @param sha_type      SHA algorithm to hash with
+ * @param input         Input message to be hashed
+ * @param num_blocks    Number of blocks to hash
+ * @param first_block   Is this the first block in a message or a continuation?
+ */
+void sha_hal_hash_dma(esp_sha_type sha_type, lldesc_t *input, size_t num_blocks, bool first_block);
+#endif
+
+#if SOC_SHA_SUPPORT_SHA512_T
+/**
+ * @brief Calculates and sets the initial digiest for SHA512_t
+ *
+ * @param t_string
+ * @param t_len
+ */
+void sha_hal_sha512_init_hash(uint32_t t_string, uint8_t t_len);
+#endif
+
+#ifdef __cplusplus
+}
+#endif

+ 34 - 0
components/soc/soc/esp32/include/soc/sha_caps.h

@@ -0,0 +1,34 @@
+// Copyright 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.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SOC_SHA_SUPPORT_DMA             (0)
+
+/* ESP32 style SHA engine, where multiple states can be stored in parallel */
+#define SOC_SHA_SUPPORT_PARALLEL_ENG    (1)
+
+/* Supported HW algorithms */
+#define SOC_SHA_SUPPORT_SHA1            (1)
+#define SOC_SHA_SUPPORT_SHA256          (1)
+#define SOC_SHA_SUPPORT_SHA384          (1)
+#define SOC_SHA_SUPPORT_SHA512          (1)
+
+#ifdef __cplusplus
+}
+#endif

+ 54 - 0
components/soc/soc/esp32s2/include/soc/sha_caps.h

@@ -0,0 +1,54 @@
+// Copyright 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.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Max amount of bytes in a single DMA operation is 4095,
+   for SHA this means that the biggest safe amount of bytes is
+   31 blocks of 128 bytes = 3968
+*/
+#define SOC_SHA_DMA_MAX_BUFFER_SIZE     (3968)
+#define SOC_SHA_SUPPORT_DMA             (1)
+
+/* ESP32 style SHA engine, where multiple states can be stored in parallel */
+#define SOC_SHA_SUPPORT_PARALLEL_ENG    (0)
+
+/* The SHA engine is able to resume hashing from a user */
+#define SOC_SHA_SUPPORT_RESUME          (1)
+
+/* Has "crypto DMA", which is shared with AES */
+#define SOC_SHA_CRYPTO_DMA              (1)
+
+/* Has a centralized DMA, which is shared with all peripherals */
+#define SOC_SHA_GENERAL_DMA             (0)
+
+/* Supported HW algorithms */
+#define SOC_SHA_SUPPORT_SHA1            (1)
+#define SOC_SHA_SUPPORT_SHA224          (1)
+#define SOC_SHA_SUPPORT_SHA256          (1)
+#define SOC_SHA_SUPPORT_SHA384          (1)
+#define SOC_SHA_SUPPORT_SHA256          (1)
+#define SOC_SHA_SUPPORT_SHA512          (1)
+#define SOC_SHA_SUPPORT_SHA512_224      (1)
+#define SOC_SHA_SUPPORT_SHA512_256      (1)
+#define SOC_SHA_SUPPORT_SHA512_T        (1)
+
+
+#ifdef __cplusplus
+}
+#endif

+ 54 - 0
components/soc/soc/esp32s3/include/soc/sha_caps.h

@@ -0,0 +1,54 @@
+// Copyright 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.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Max amount of bytes in a single DMA operation is 4095,
+   for SHA this means that the biggest safe amount of bytes is
+   31 blocks of 128 bytes = 3968
+*/
+#define SOC_SHA_DMA_MAX_BUFFER_SIZE     (3968)
+#define SOC_SHA_SUPPORT_DMA             (1)
+
+/* ESP32 style SHA engine, where multiple states can be stored in parallel */
+#define SOC_SHA_SUPPORT_PARALLEL_ENG    (0)
+
+/* The SHA engine is able to resume hashing from a user */
+#define SOC_SHA_SUPPORT_RESUME          (1)
+
+/* Has "crypto DMA", which is shared with AES */
+#define SOC_SHA_CRYPTO_DMA              (0)
+
+/* Has a centralized DMA, which is shared with all peripherals */
+#define SOC_SHA_GENERAL_DMA             (1)
+
+/* Supported HW algorithms */
+#define SOC_SHA_SUPPORT_SHA1            (1)
+#define SOC_SHA_SUPPORT_SHA224          (1)
+#define SOC_SHA_SUPPORT_SHA256          (1)
+#define SOC_SHA_SUPPORT_SHA384          (1)
+#define SOC_SHA_SUPPORT_SHA256          (1)
+#define SOC_SHA_SUPPORT_SHA512          (1)
+#define SOC_SHA_SUPPORT_SHA512_224      (1)
+#define SOC_SHA_SUPPORT_SHA512_256      (1)
+#define SOC_SHA_SUPPORT_SHA512_T        (1)
+
+
+#ifdef __cplusplus
+}
+#endif

+ 2 - 1
components/soc/soc/esp32s3/include/soc/soc_caps.h

@@ -14,4 +14,5 @@
 // Remove them when GDMA driver API is ready
 #define SOC_GDMA_M2M_DMA_CHANNEL  (0)
 #define SOC_GDMA_SPI2_DMA_CHANNEL (1)
-#define SOC_GDMA_SPI3_DMA_CHANNEL (2)
+#define SOC_GDMA_SPI3_DMA_CHANNEL (2)
+#define SOC_GDMA_SHA_DMA_CHANNEL  (3)