From bbdeff1da1b58210c0e94d75920b15f1eef2da56 Mon Sep 17 00:00:00 2001 From: Konstantin Kondrashov Date: Mon, 13 May 2019 12:32:45 +0800 Subject: [PATCH] esp32: Rewrite esp_sha function It removes using a STALL_OTHER_CPU while sha operations. It improves performance with SHA. --- components/esp_rom/include/esp32/rom/sha.h | 3 + components/mbedtls/CMakeLists.txt | 1 + components/mbedtls/port/esp32/sha.c | 61 ----------------- components/mbedtls/port/esp_sha.c | 79 ++++++++++++++++++++++ 4 files changed, 83 insertions(+), 61 deletions(-) create mode 100644 components/mbedtls/port/esp_sha.c diff --git a/components/esp_rom/include/esp32/rom/sha.h b/components/esp_rom/include/esp32/rom/sha.h index 888c32c3c..323749efd 100644 --- a/components/esp_rom/include/esp32/rom/sha.h +++ b/components/esp_rom/include/esp32/rom/sha.h @@ -44,6 +44,9 @@ enum SHA_TYPE { SHA_INVALID = -1, }; +/* 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); void ets_sha_enable(void); diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 364923427..09abc2fff 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -81,6 +81,7 @@ set(mbedtls_targets mbedtls mbedcrypto mbedx509) target_sources(mbedtls PRIVATE "${COMPONENT_PATH}/port/esp_bignum.c" "${COMPONENT_PATH}/port/esp_hardware.c" "${COMPONENT_PATH}/port/esp_mem.c" + "${COMPONENT_PATH}/port/esp_sha.c" "${COMPONENT_PATH}/port/esp_sha1.c" "${COMPONENT_PATH}/port/esp_sha256.c" "${COMPONENT_PATH}/port/esp_sha512.c" diff --git a/components/mbedtls/port/esp32/sha.c b/components/mbedtls/port/esp32/sha.c index 4cff99575..0f8a4ca0a 100644 --- a/components/mbedtls/port/esp32/sha.c +++ b/components/mbedtls/port/esp32/sha.c @@ -183,9 +183,6 @@ static bool esp_sha_lock_engine_common(esp_sha_type sha_type, TickType_t ticks_t /* Just locked first engine, so enable SHA hardware */ periph_module_enable(PERIPH_SHA_MODULE); - DPORT_STALL_OTHER_CPU_START(); - ets_sha_enable(); - DPORT_STALL_OTHER_CPU_END(); } engines_in_use++; @@ -305,61 +302,3 @@ void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_ unit, instead. */ } - -void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output) -{ - size_t block_len = block_length(sha_type); - - // Max number of blocks to pass per each call to esp_sha_lock_memory_block() - // (keep low enough to avoid starving interrupt handlers, especially if reading - // data into SHA via flash cache, but high enough that spinlock overhead is low) - const size_t BLOCKS_PER_CHUNK = 100; - const size_t MAX_CHUNK_LEN = BLOCKS_PER_CHUNK * block_len; - - SHA_CTX ctx; - - esp_sha_lock_engine(sha_type); - - ets_sha_init(&ctx); - - while (ilen > 0) { - size_t chunk_len = (ilen > MAX_CHUNK_LEN) ? MAX_CHUNK_LEN : ilen; - - // Wait for idle before entering critical section - // (to reduce time spent in it), then check again after - esp_sha_wait_idle(); - esp_sha_lock_memory_block(); - esp_sha_wait_idle(); - - DPORT_STALL_OTHER_CPU_START(); - while (chunk_len > 0) { - // This SHA ROM function reads DPORT regs - // (can accept max one SHA block each call) - size_t update_len = (chunk_len > block_len) ? block_len : chunk_len; - ets_sha_update(&ctx, sha_type, input, update_len * 8); - - input += update_len; - chunk_len -= update_len; - ilen -= update_len; - } - DPORT_STALL_OTHER_CPU_END(); - - if (ilen == 0) { - /* Finish the last block before releasing the memory - block lock, as ets_sha_update() may have written data to - the memory block already (partial last block) and hardware - hasn't yet processed it. - */ - DPORT_STALL_OTHER_CPU_START(); - { - // This SHA ROM function also reads DPORT regs - ets_sha_finish(&ctx, sha_type, output); - } - DPORT_STALL_OTHER_CPU_END(); - } - - esp_sha_unlock_memory_block(); - } - - esp_sha_unlock_engine(sha_type); -} diff --git a/components/mbedtls/port/esp_sha.c b/components/mbedtls/port/esp_sha.c new file mode 100644 index 000000000..2c40f2c5d --- /dev/null +++ b/components/mbedtls/port/esp_sha.c @@ -0,0 +1,79 @@ +// Copyright 2018-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. + +#include +#include +#include + +#include "esp32/sha.h" +#include +#include +#include + +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 (sha_type == SHA1) { + + mbedtls_sha1_context *ctx1 = (mbedtls_sha1_context *)malloc(sizeof(mbedtls_sha1_context)); + assert(ctx1 != NULL); + mbedtls_sha1_starts_ret(ctx1); + ret = mbedtls_sha1_update_ret(ctx1, input, ilen); + assert(ret == 0); + ret = mbedtls_sha1_finish_ret(ctx1, output); + assert(ret == 0); + mbedtls_sha1_free(ctx1); + free(ctx1); + + } else 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); + ret = mbedtls_sha256_update_ret(ctx256, input, ilen); + assert(ret == 0); + ret = mbedtls_sha256_finish_ret(ctx256, output); + assert(ret == 0); + mbedtls_sha256_free(ctx256); + free(ctx256); + + } else 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); + ret = mbedtls_sha512_update_ret(ctx384, input, ilen); + assert(ret == 0); + ret = mbedtls_sha512_finish_ret(ctx384, output); + assert(ret == 0); + mbedtls_sha512_free(ctx384); + free(ctx384); + + } else 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); + ret = mbedtls_sha512_update_ret(ctx512, input, ilen); + assert(ret == 0); + ret = mbedtls_sha512_finish_ret(ctx512, output); + assert(ret == 0); + mbedtls_sha512_free(ctx512); + free(ctx512); + + } + +}