diff --git a/components/esp32/test/test_aes_sha_rsa.c b/components/esp32/test/test_aes_sha_rsa.c index bfb48e606c..c18850a190 100644 --- a/components/esp32/test/test_aes_sha_rsa.c +++ b/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" diff --git a/components/esp32/test/test_sha.c b/components/esp32/test/test_sha.c index 5a1f3942a9..cbc1479159 100644 --- a/components/esp32/test/test_sha.c +++ b/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 diff --git a/components/esp32s2/test/test_sha.c b/components/esp32s2/test/test_sha.c index bd8bd9be14..e483f9248f 100644 --- a/components/esp32s2/test/test_sha.c +++ b/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. diff --git a/components/esp32s3/CMakeLists.txt b/components/esp32s3/CMakeLists.txt index 1d060d9a4b..8d40232bd8 100644 --- a/components/esp32s3/CMakeLists.txt +++ b/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" diff --git a/components/esp32s3/esp_crypto_lock.c b/components/esp32s3/esp_crypto_lock.c new file mode 100644 index 0000000000..8e72294b19 --- /dev/null +++ b/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 + +#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); +} \ No newline at end of file diff --git a/components/esp32s3/include/esp_crypto_lock.h b/components/esp32s3/include/esp_crypto_lock.h new file mode 100644 index 0000000000..bf30ba318c --- /dev/null +++ b/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 diff --git a/components/esp_rom/include/esp32/rom/sha.h b/components/esp_rom/include/esp32/rom/sha.h index 323749efdd..f43c19d16a 100644 --- a/components/esp_rom/include/esp32/rom/sha.h +++ b/components/esp_rom/include/esp32/rom/sha.h @@ -24,6 +24,7 @@ #include #include +#include #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); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 0384e7587b..6dd45d3678 100644 --- a/components/hal/CMakeLists.txt +++ b/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") diff --git a/components/hal/esp32/include/hal/sha_ll.h b/components/hal/esp32/include/hal/sha_ll.h new file mode 100644 index 0000000000..65cfa78551 --- /dev/null +++ b/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 +#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)®_addr_buf[i]); + digest_state_words[i] = DPORT_SEQUENCE_REG_READ((uint32_t)®_addr_buf[i + 1]); + } + DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level + } else { + esp_dport_access_read_buffer(digest_state_words, (uint32_t)®_addr_buf[0], digest_word_len); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s2/include/hal/crypto_dma_ll.h b/components/hal/esp32s2/include/hal/crypto_dma_ll.h new file mode 100644 index 0000000000..075aa0bd09 --- /dev/null +++ b/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 + + + diff --git a/components/hal/esp32s2/include/hal/sha_ll.h b/components/hal/esp32s2/include/hal/sha_ll.h new file mode 100644 index 0000000000..0a5e1b6ce3 --- /dev/null +++ b/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 +#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(®_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(®_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 diff --git a/components/hal/esp32s3/include/hal/clk_gate_ll.h b/components/hal/esp32s3/include/hal/clk_gate_ll.h index 94cca9f93f..7c073b8e69 100644 --- a/components/hal/esp32s3/include/hal/clk_gate_ll.h +++ b/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: diff --git a/components/hal/esp32s3/include/hal/sha_ll.h b/components/hal/esp32s3/include/hal/sha_ll.h new file mode 100644 index 0000000000..11da3276fc --- /dev/null +++ b/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 +#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(®_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(®_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 diff --git a/components/hal/include/hal/sha_types.h b/components/hal/include/hal/sha_types.h new file mode 100644 index 0000000000..c503822766 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/components/hal/sha_hal.c b/components/hal/sha_hal.c new file mode 100644 index 0000000000..866524f83c --- /dev/null +++ b/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 +#include + +#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 \ No newline at end of file diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 6dfdfcfa7c..cefca19aa4 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/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() diff --git a/components/mbedtls/component.mk b/components/mbedtls/component.mk index 196370dff2..7bd137a5b4 100644 --- a/components/mbedtls/component.mk +++ b/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 diff --git a/components/mbedtls/port/esp32s2/esp_sha1.c b/components/mbedtls/port/esp32s2/esp_sha1.c deleted file mode 100644 index f84b627748..0000000000 --- a/components/mbedtls/port/esp32s2/esp_sha1.c +++ /dev/null @@ -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 - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#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 */ diff --git a/components/mbedtls/port/esp32s2/esp_sha256.c b/components/mbedtls/port/esp32s2/esp_sha256.c deleted file mode 100644 index f7ecf3e10e..0000000000 --- a/components/mbedtls/port/esp32s2/esp_sha256.c +++ /dev/null @@ -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 - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#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 */ diff --git a/components/mbedtls/port/esp32s3/esp_sha512.c b/components/mbedtls/port/esp32s3/esp_sha512.c deleted file mode 100644 index 20a43ad03c..0000000000 --- a/components/mbedtls/port/esp32s3/esp_sha512.c +++ /dev/null @@ -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 - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#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 */ diff --git a/components/mbedtls/port/esp32s3/sha.c b/components/mbedtls/port/esp32s3/sha.c deleted file mode 100644 index e2dc8ff20a..0000000000 --- a/components/mbedtls/port/esp32s3/sha.c +++ /dev/null @@ -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 -#include -#include -#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(®_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; -} - diff --git a/components/mbedtls/port/include/esp32/sha.h b/components/mbedtls/port/include/esp32/sha.h index 2009d19818..b99d613c95 100644 --- a/components/mbedtls/port/include/esp32/sha.h +++ b/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 \ No newline at end of file diff --git a/components/mbedtls/port/include/esp32s2/sha.h b/components/mbedtls/port/include/esp32s2/sha.h index 58bd439412..12c6548d62 100644 --- a/components/mbedtls/port/include/esp32s2/sha.h +++ b/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. - * - */ - -#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); +#warning esp32s2/sha.h is deprecated, please use sha/sha_dma.h instead -/** - * @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 - diff --git a/components/mbedtls/port/include/esp32s3/sha.h b/components/mbedtls/port/include/sha/sha_dma.h similarity index 97% rename from components/mbedtls/port/include/esp32s3/sha.h rename to components/mbedtls/port/include/sha/sha_dma.h index 960d63b770..c71261d101 100644 --- a/components/mbedtls/port/include/esp32s3/sha.h +++ b/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 diff --git a/components/mbedtls/port/include/sha/sha_parallel_engine.h b/components/mbedtls/port/include/sha/sha_parallel_engine.h new file mode 100644 index 0000000000..51ac7add8d --- /dev/null +++ b/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 + + diff --git a/components/mbedtls/port/include/sha1_alt.h b/components/mbedtls/port/include/sha1_alt.h index 628607518e..7c145ae5f2 100644 --- a/components/mbedtls/port/include/sha1_alt.h +++ b/components/mbedtls/port/include/sha1_alt.h @@ -23,57 +23,16 @@ #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 - -#include "esp32s3/sha.h" -typedef enum { - ESP_SHA1_STATE_INIT, - ESP_SHA1_STATE_IN_PROCESS -} esp_sha1_state; - -/** - * \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 */ - int first_block; /*!< if first then true else false */ - esp_sha_type mode; - esp_sha1_state sha_state; -} mbedtls_sha1_context; - -#endif //CONFIG_IDF_TARGET_ESP32S3 - -#if CONFIG_IDF_TARGET_ESP32S2 - -#include "esp32s2/sha.h" -typedef enum { - ESP_SHA1_STATE_INIT, - ESP_SHA1_STATE_IN_PROCESS -} esp_sha1_state; - -/** - * \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 */ - int first_block; /*!< if first then true else false */ - esp_sha_type mode; - esp_sha1_state sha_state; -} mbedtls_sha1_context; - -#endif //CONFIG_IDF_TARGET_ESP32S2 - -#if CONFIG_IDF_TARGET_ESP32 +#if SOC_SHA_SUPPORT_PARALLEL_ENG typedef enum { ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */ @@ -89,10 +48,28 @@ typedef struct { uint32_t state[5]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ esp_mbedtls_sha1_mode mode; -} -mbedtls_sha1_context; +} mbedtls_sha1_context; -#endif //CONFIG_IDF_TARGET_ESP32 +#elif SOC_SHA_SUPPORT_DMA + +typedef enum { + ESP_SHA1_STATE_INIT, + ESP_SHA1_STATE_IN_PROCESS +} esp_sha1_state; + +/** + * \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 */ + int first_block; /*!< if first then true else false */ + esp_sha_type mode; + esp_sha1_state sha_state; +} mbedtls_sha1_context; + +#endif #endif diff --git a/components/mbedtls/port/include/sha256_alt.h b/components/mbedtls/port/include/sha256_alt.h index fabb22f9ad..3a1f385e9a 100644 --- a/components/mbedtls/port/include/sha256_alt.h +++ b/components/mbedtls/port/include/sha256_alt.h @@ -23,62 +23,16 @@ #ifndef _SHA256_ALT_H_ #define _SHA256_ALT_H_ +#if defined(MBEDTLS_SHA256_ALT) + +#include "hal/sha_types.h" +#include "soc/sha_caps.h" + #ifdef __cplusplus extern "C" { #endif -#if defined(MBEDTLS_SHA256_ALT) - -#if CONFIG_IDF_TARGET_ESP32S3 - -#include "esp32s3/sha.h" - -typedef enum { - ESP_SHA256_STATE_INIT, - ESP_SHA256_STATE_IN_PROCESS -} esp_sha256_state; - -/** - * \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 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" - -typedef enum { - ESP_SHA256_STATE_INIT, - ESP_SHA256_STATE_IN_PROCESS -} esp_sha256_state; - -/** - * \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 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 - +#if SOC_SHA_SUPPORT_PARALLEL_ENG typedef enum { ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */ ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */ @@ -94,10 +48,27 @@ typedef struct { 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 +#elif SOC_SHA_SUPPORT_DMA +typedef enum { + ESP_SHA256_STATE_INIT, + ESP_SHA256_STATE_IN_PROCESS +} esp_sha256_state; + +/** + * \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 first_block; /*!< if first then true, else false */ + esp_sha_type mode; + esp_sha256_state sha_state; +} mbedtls_sha256_context; + +#endif #endif diff --git a/components/mbedtls/port/include/sha512_alt.h b/components/mbedtls/port/include/sha512_alt.h index d5c5f6981d..4f5cc005e6 100644 --- a/components/mbedtls/port/include/sha512_alt.h +++ b/components/mbedtls/port/include/sha512_alt.h @@ -23,86 +23,17 @@ #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" - -typedef enum { - ESP_SHA512_STATE_INIT, - ESP_SHA512_STATE_IN_PROCESS -} esp_sha512_state; - -/** - * \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 first_block; - esp_sha_type mode; - uint32_t t_val; /*!< t_val for 512/t mode */ - esp_sha512_state sha_state; -} 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" - -typedef enum { - ESP_SHA512_STATE_INIT, - ESP_SHA512_STATE_IN_PROCESS -} esp_sha512_state; - -/** - * \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 first_block; - esp_sha_type mode; - uint32_t t_val; /*!< t_val for 512/t mode */ - esp_sha512_state sha_state; -} 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_ESP32S2 - -#if CONFIG_IDF_TARGET_ESP32 +#if SOC_SHA_SUPPORT_PARALLEL_ENG typedef enum { ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */ @@ -119,10 +50,43 @@ typedef struct { unsigned char buffer[128]; /*!< data block being processed */ int is384; /*!< 0 => SHA-512, else SHA-384 */ esp_mbedtls_sha512_mode mode; -} -mbedtls_sha512_context; +} mbedtls_sha512_context; -#endif //CONFIG_IDF_TARGET_ESP32 +#elif SOC_SHA_SUPPORT_DMA + +typedef enum { + ESP_SHA512_STATE_INIT, + ESP_SHA512_STATE_IN_PROCESS +} esp_sha512_state; + +/** + * \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 first_block; + esp_sha_type mode; + uint32_t t_val; /*!< t_val for 512/t mode */ + esp_sha512_state sha_state; +} 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 #endif diff --git a/components/mbedtls/port/esp32s3/esp_sha1.c b/components/mbedtls/port/sha/dma/esp_sha1.c similarity index 95% rename from components/mbedtls/port/esp32s3/esp_sha1.c rename to components/mbedtls/port/sha/dma/esp_sha1.c index 1890fc7369..32b74ba448 100644 --- a/components/mbedtls/port/esp32s3/esp_sha1.c +++ b/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; diff --git a/components/mbedtls/port/esp32s3/esp_sha256.c b/components/mbedtls/port/sha/dma/esp_sha256.c similarity index 96% rename from components/mbedtls/port/esp32s3/esp_sha256.c rename to components/mbedtls/port/sha/dma/esp_sha256.c index ba1e60753a..307b338498 100644 --- a/components/mbedtls/port/esp32s3/esp_sha256.c +++ b/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; + } } /* diff --git a/components/mbedtls/port/esp32s2/esp_sha512.c b/components/mbedtls/port/sha/dma/esp_sha512.c similarity index 96% rename from components/mbedtls/port/esp32s2/esp_sha512.c rename to components/mbedtls/port/sha/dma/esp_sha512.c index 155ee25b1d..fa4465d0f8 100644 --- a/components/mbedtls/port/esp32s2/esp_sha512.c +++ b/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; + } } /* diff --git a/components/mbedtls/port/esp32s2/sha.c b/components/mbedtls/port/sha/dma/sha.c similarity index 59% rename from components/mbedtls/port/esp32s2/sha.c rename to components/mbedtls/port/sha/dma/sha.c index 6b0723967f..e3964efd8a 100644 --- a/components/mbedtls/port/esp32s2/sha.c +++ b/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(®_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); + sha_hal_hash_dma(sha_type, dma_descr_head, num_blks, is_first_block); - /* 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; } diff --git a/components/mbedtls/port/esp_sha.c b/components/mbedtls/port/sha/esp_sha.c similarity index 78% rename from components/mbedtls/port/esp_sha.c rename to components/mbedtls/port/sha/esp_sha.c index 1791cbf3ca..c61be3730c 100644 --- a/components/mbedtls/port/esp_sha.c +++ b/components/mbedtls/port/sha/esp_sha.c @@ -15,26 +15,29 @@ #include #include #include -#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 #include #include +#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(); } diff --git a/components/mbedtls/port/esp32/esp_sha1.c b/components/mbedtls/port/sha/parallel_engine/esp_sha1.c similarity index 95% rename from components/mbedtls/port/esp32/esp_sha1.c rename to components/mbedtls/port/sha/parallel_engine/esp_sha1.c index ba5231b9ce..4700daf553 100644 --- a/components/mbedtls/port/esp32/esp_sha1.c +++ b/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 ); diff --git a/components/mbedtls/port/esp32/esp_sha256.c b/components/mbedtls/port/sha/parallel_engine/esp_sha256.c similarity index 82% rename from components/mbedtls/port/esp32/esp_sha256.c rename to components/mbedtls/port/sha/parallel_engine/esp_sha256.c index 7a1e2a1475..c29ffebb7d 100644 --- a/components/mbedtls/port/esp32/esp_sha256.c +++ b/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 = 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 = 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] ); } #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) { diff --git a/components/mbedtls/port/esp32/esp_sha512.c b/components/mbedtls/port/sha/parallel_engine/esp_sha512.c similarity index 94% rename from components/mbedtls/port/esp32/esp_sha512.c rename to components/mbedtls/port/sha/parallel_engine/esp_sha512.c index 58cd79097f..fd9c354d15 100644 --- a/components/mbedtls/port/esp32/esp_sha512.c +++ b/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 @@ -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 ); } diff --git a/components/mbedtls/port/esp32/sha.c b/components/mbedtls/port/sha/parallel_engine/sha.c similarity index 60% rename from components/mbedtls/port/esp32/sha.c rename to components/mbedtls/port/sha/parallel_engine/sha.c index ddb2eee5ca..a87ced376a 100644 --- a/components/mbedtls/port/esp32/sha.c +++ b/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,9 +63,25 @@ static uint8_t engines_in_use; */ static portMUX_TYPE engines_in_use_lock = portMUX_INITIALIZER_UNLOCKED; +/* Return block size (in words) for a given SHA type */ +inline static size_t block_length(esp_sha_type type) +{ + switch (type) { + case SHA1: + case SHA2_256: + return 64 / 4; + case SHA2_384: + case SHA2_512: + return 128 / 4; + default: + return 0; + } +} + /* Index into the engine_states array */ -inline static size_t sha_engine_index(esp_sha_type type) { - switch(type) { +inline static size_t sha_engine_index(esp_sha_type type) +{ + switch (type) { case SHA1: return 0; case SHA2_256: @@ -88,36 +91,6 @@ inline static size_t sha_engine_index(esp_sha_type type) { } } -/* Return digest length (in bytes) for a given SHA type */ -inline static size_t sha_length(esp_sha_type type) { - switch(type) { - case SHA1: - return 20; - case SHA2_256: - return 32; - case SHA2_384: - return 48; - case SHA2_512: - return 64; - 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) { - case SHA1: - case SHA2_256: - return 64; - case SHA2_384: - case SHA2_512: - return 128; - default: - return 0; - } -} - void esp_sha_lock_memory_block(void) { portENTER_CRITICAL(&memory_block_lock); @@ -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(); + sha_hal_read_digest(sha_type, digest_state); - 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)®_addr_buf[i]); - digest_state_words[i] = DPORT_SEQUENCE_REG_READ((uint32_t)®_addr_buf[i+1]); - } - DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level - } else { - esp_dport_access_read_buffer(digest_state_words, (uint32_t)®_addr_buf[0], word_len); - } esp_sha_unlock_memory_block(); - - /* 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 } -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. - */ } diff --git a/components/soc/include/hal/sha_hal.h b/components/soc/include/hal/sha_hal.h new file mode 100644 index 0000000000..ff3e7e233f --- /dev/null +++ b/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 +#include +#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 diff --git a/components/soc/soc/esp32/include/soc/sha_caps.h b/components/soc/soc/esp32/include/soc/sha_caps.h new file mode 100644 index 0000000000..b409013f30 --- /dev/null +++ b/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 diff --git a/components/soc/soc/esp32s2/include/soc/sha_caps.h b/components/soc/soc/esp32s2/include/soc/sha_caps.h new file mode 100644 index 0000000000..10118590ed --- /dev/null +++ b/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 diff --git a/components/soc/soc/esp32s3/include/soc/sha_caps.h b/components/soc/soc/esp32s3/include/soc/sha_caps.h new file mode 100644 index 0000000000..63ea748512 --- /dev/null +++ b/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 diff --git a/components/soc/soc/esp32s3/include/soc/soc_caps.h b/components/soc/soc/esp32s3/include/soc/soc_caps.h index 1e19ad7fb8..e6225a1135 100644 --- a/components/soc/soc/esp32s3/include/soc/soc_caps.h +++ b/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) \ No newline at end of file +#define SOC_GDMA_SPI3_DMA_CHANNEL (2) +#define SOC_GDMA_SHA_DMA_CHANNEL (3)