mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp32: Rewrite esp_sha function
It removes using a STALL_OTHER_CPU while sha operations. It improves performance with SHA.
This commit is contained in:
parent
014de712ab
commit
bbdeff1da1
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
79
components/mbedtls/port/esp_sha.c
Normal file
79
components/mbedtls/port/esp_sha.c
Normal file
@ -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 <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "esp32/sha.h"
|
||||
#include <mbedtls/sha1.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/sha512.h>
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user