This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 82effd4b2f xtensa/esp32: Add support for hardware accelerated SHA 82effd4b2f is described below commit 82effd4b2f3e9ad78f38e41beb22b7703a4e6986 Author: Vlad Pruteanu <pruteanuvlad1...@yahoo.com> AuthorDate: Sat Mar 8 18:26:33 2025 +0200 xtensa/esp32: Add support for hardware accelerated SHA This enables the use of the cryptographic accelerator within the ESP32. The support algorithms are: SHA1, SHA256, SHA384 and SHA512. Signed-off-by: Vlad Pruteanu <pruteanuvlad1...@yahoo.com> --- .../xtensa/esp32/boards/esp32-devkitc/index.rst | 7 + Documentation/platforms/xtensa/esp32/index.rst | 2 +- arch/xtensa/src/esp32/Kconfig | 5 + arch/xtensa/src/esp32/Make.defs | 8 + arch/xtensa/src/esp32/esp32_crypto.c | 567 +++++++++++++++++++++ arch/xtensa/src/esp32/esp32_sha.c | 399 +++++++++++++++ arch/xtensa/src/esp32/esp32_sha.h | 226 ++++++++ arch/xtensa/src/esp32/hal.mk | 2 + .../esp32/esp32-devkitc/configs/crypto/defconfig | 57 +++ 9 files changed, 1272 insertions(+), 1 deletion(-) diff --git a/Documentation/platforms/xtensa/esp32/boards/esp32-devkitc/index.rst b/Documentation/platforms/xtensa/esp32/boards/esp32-devkitc/index.rst index 8aaba387e0..30c69266cc 100644 --- a/Documentation/platforms/xtensa/esp32/boards/esp32-devkitc/index.rst +++ b/Documentation/platforms/xtensa/esp32/boards/esp32-devkitc/index.rst @@ -360,6 +360,13 @@ disables the NuttShell to get the best possible score. .. note:: As the NSH is disabled, the application will start as soon as the system is turned on. +crypto +-------- + +This configuration enables support for the cryptographic hardware and +the /dev/crypto device file. Currently, only the hashing operation is +supported. + cxx --- diff --git a/Documentation/platforms/xtensa/esp32/index.rst b/Documentation/platforms/xtensa/esp32/index.rst index 534cb9de66..fec15b9745 100644 --- a/Documentation/platforms/xtensa/esp32/index.rst +++ b/Documentation/platforms/xtensa/esp32/index.rst @@ -417,7 +417,7 @@ RSA No RTC Yes SD/MMC No SDIO No -SHA No +SHA Yes SPI Yes SPIFLASH Yes SPIRAM Yes diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index 4d7bcb2b8a..4cdf20047b 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -794,6 +794,11 @@ config ESP32_TWAI0 config ESP32_AES_ACCELERATOR bool "AES Accelerator" default n +config ESP32_SHA_ACCELERATOR + bool "SHA Accelerator" + default n + ---help--- + Enable ESP32 SHA accelerator support. config ESP32_PID bool "PID Controller" diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index c0fd584a23..2ed06ab631 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -192,6 +192,14 @@ ifeq ($(CONFIG_ESP32_AES_ACCELERATOR),y) CHIP_CSRCS += esp32_aes.c endif +ifeq ($(CONFIG_ESP32_SHA_ACCELERATOR),y) +CHIP_CSRCS += esp32_sha.c +endif + +ifeq ($(CONFIG_CRYPTO_CRYPTODEV_HARDWARE),y) +CHIP_CSRCS += esp32_crypto.c +endif + ifeq ($(CONFIG_ESP32_RTC),y) CHIP_CSRCS += esp32_rtc.c ifeq ($(CONFIG_RTC_DRIVER),y) diff --git a/arch/xtensa/src/esp32/esp32_crypto.c b/arch/xtensa/src/esp32/esp32_crypto.c new file mode 100644 index 0000000000..6ec2f4e605 --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_crypto.c @@ -0,0 +1,567 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_crypto.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <errno.h> +#include <stddef.h> +#include <sys/queue.h> + +#include <crypto/cryptodev.h> +#include <crypto/xform.h> +#include <nuttx/kmalloc.h> +#include <nuttx/crypto/crypto.h> + +#include "esp32_sha.h" +#include <stdio.h> + +/**************************************************************************** + * Private Functions Prototypes + ****************************************************************************/ + +static void sha1_init(void *ctx); +static void sha256_init(void *ctx); +static void sha384_init(void *ctx); +static void sha512_init(void *ctx); +static int sha_update(void *ctx, const uint8_t *in, size_t len); +static void sha_final(uint8_t *out, void *ctx); +static int esp32_freesession(uint64_t sid); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +SLIST_HEAD(esp32_crypto_list, esp32_crypto_data); +static struct esp32_crypto_list *g_esp32_sessions = NULL; +static uint32_t g_esp32_sesnum = 0; + +const struct auth_hash g_auth_hash_sha1_esp32 = +{ + CRYPTO_SHA1, "SHA1", + 0, 20, 12, sizeof(struct esp32_sha_context_s), + 0, + sha1_init, NULL, NULL, + sha_update, + sha_final +}; + +const struct auth_hash g_auth_hash_sha2_256_esp32 = +{ + CRYPTO_SHA2_256, "SHA256", + 0, 32, 12, sizeof(struct esp32_sha_context_s), + 0, + sha256_init, NULL, NULL, + sha_update, + sha_final +}; + +const struct auth_hash g_auth_hash_sha2_384_esp32 = +{ + CRYPTO_SHA2_384, "SHA384", + 0, 48, 12, sizeof(struct esp32_sha_context_s), + 0, + sha384_init, NULL, NULL, + sha_update, + sha_final +}; + +const struct auth_hash g_auth_hash_sha2_512_esp32 = +{ + CRYPTO_SHA2_512, "SHA512", + 0, 64, 12, sizeof(struct esp32_sha_context_s), + 0, + sha512_init, NULL, NULL, + sha_update, + sha_final +}; + +struct esp32_crypto_data +{ + int alg; /* Algorithm */ + union + { + struct + { + uint8_t *ictx; + uint8_t *octx; + uint32_t klen; + const struct auth_hash *axf; + } HWCR_AUTH; + } HWCR_UN; + +#define hw_ictx HWCR_UN.HWCR_AUTH.ictx +#define hw_octx HWCR_UN.HWCR_AUTH.octx +#define hw_klen HWCR_UN.HWCR_AUTH.klen +#define hw_axf HWCR_UN.HWCR_AUTH.axf + + SLIST_ENTRY(esp32_crypto_data) next; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sha1_init + * + * Description: + * Initialize the SHA-1 context. + * + * Input Parameters: + * ctx - The SHA-1 context to be initialized + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sha1_init(void *ctx) +{ + esp32_sha1_starts(ctx); +} + +/**************************************************************************** + * Name: sha256_init + * + * Description: + * Initialize the SHA-256 context. + * + * Input Parameters: + * ctx - The SHA-256 context to be initialized + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sha256_init(void *ctx) +{ + esp32_sha256_starts(ctx); +} + +/**************************************************************************** + * Name: sha384_init + * + * Description: + * Initialize the SHA-384 context. + * + * Input Parameters: + * ctx - The SHA-384 context to be initialized + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sha384_init(void *ctx) +{ + esp32_sha384_starts(ctx); +} + +/**************************************************************************** + * Name: sha512_init + * + * Description: + * Initialize the SHA-512 context. + * + * Input Parameters: + * ctx - The SHA-512 context to be initialized + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sha512_init(void *ctx) +{ + esp32_sha512_starts(ctx); +} + +/**************************************************************************** + * Name: sha_update + * + * Description: + * Feeds an input buffer into an ongoing SHA checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to use + * in - The buffer holding the input data + * len - The length of the input data in Bytes + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +static int sha_update(void *ctx, const uint8_t *in, size_t len) +{ + return esp32_sha_update((struct esp32_sha_context_s *)ctx, + (const unsigned char *)in, + (size_t)len); +} + +/**************************************************************************** + * Name: sha_final + * + * Description: + * Finishes the SHA operation, and writes the result to the output buffer. + * + * Input Parameters: + * out - The SHA checksum result + * ctx - The SHA context to use + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +static void sha_final(uint8_t *out, void *ctx) +{ + esp32_sha_finish((struct esp32_sha_context_s *)ctx, + (unsigned char *)out); +} + +/**************************************************************************** + * Name: hash + * + * Description: + * Calculate the hash. + * + * Input Parameters: + * crp - The description of the crypto operation + * crd - Boundaries of the crypto operation + * data - ESP32 specific crypto operation data + * buf - Input data to be hashed + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +static int hash(struct cryptop *crp, + struct cryptodesc *crd, + struct esp32_crypto_data *data, + caddr_t buf) +{ + const struct auth_hash *axf; + + if (data->hw_ictx == 0) + { + return -EINVAL; + } + + axf = data->hw_axf; + + if (crd->crd_flags & CRD_F_UPDATE) + { + return axf->update(data->hw_ictx, (uint8_t *)buf, crd->crd_len); + } + else + { + axf->final((uint8_t *)crp->crp_mac, data->hw_ictx); + } + + return 0; +} + +/**************************************************************************** + * Name: esp32_newsession + * + * Description: + * create new session for crypto. + * + * Input Parameters: + * sid - Session id + * cri - Initialization structure + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +static int esp32_newsession(uint32_t *sid, struct cryptoini *cri) +{ + struct esp32_crypto_list *session; + struct esp32_crypto_data *prev = NULL; + struct esp32_crypto_data *data; + const struct auth_hash *axf; + int i; + int k; + + if (sid == NULL || cri == NULL) + { + return -EINVAL; + } + + for (i = 0; i < g_esp32_sesnum; i++) + { + if (SLIST_EMPTY(&g_esp32_sessions[i])) + { + break; + } + } + + if (i >= g_esp32_sesnum) + { + if (g_esp32_sessions == NULL) + { + g_esp32_sesnum = 1; + } + else + { + g_esp32_sesnum *= 2; + } + + session = kmm_calloc(g_esp32_sesnum, + sizeof(struct esp32_crypto_list)); + if (session == NULL) + { + g_esp32_sesnum /= 2; + return -ENOBUFS; + } + + if (g_esp32_sessions != NULL) + { + bcopy(g_esp32_sessions, session, (g_esp32_sesnum / 2) * + sizeof(struct esp32_crypto_list)); + kmm_free(g_esp32_sessions); + } + + g_esp32_sessions = session; + } + + session = &g_esp32_sessions[i]; + *sid = i; + + while (cri) + { + data = kmm_malloc(sizeof(struct esp32_crypto_data)); + + if (data == NULL) + { + esp32_freesession(i); + return -ENOBUFS; + } + + switch (cri->cri_alg) + { + case CRYPTO_SHA1: + axf = &g_auth_hash_sha1_esp32; + goto common; + case CRYPTO_SHA2_256: + axf = &g_auth_hash_sha2_256_esp32; + goto common; + case CRYPTO_SHA2_384: + axf = &g_auth_hash_sha2_384_esp32; + goto common; + case CRYPTO_SHA2_512: + axf = &g_auth_hash_sha2_512_esp32; + goto common; + common: + data->hw_ictx = kmm_malloc(axf->ctxsize); + if (data->hw_ictx == NULL) + { + kmm_free(data); + return -ENOBUFS; + } + + axf->init(data->hw_ictx); + data->hw_axf = axf; + break; + + default: + esp32_freesession(i); + kmm_free(data); + return -EINVAL; + } + + if (prev == NULL) + { + SLIST_INSERT_HEAD(session, data, next); + } + else + { + SLIST_INSERT_AFTER(prev, data, next); + } + + data->alg = cri->cri_alg; + cri = cri->cri_next; + prev = data; + } + + return OK; +} + +/**************************************************************************** + * Name: esp32_freesession + * + * Description: + * free session. + * + * Input Parameters: + * sid - Session id + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +static int esp32_freesession(uint64_t sid) +{ + struct esp32_crypto_list *session; + struct esp32_crypto_data *data; + const struct auth_hash *axf; + + if (sid > g_esp32_sesnum || SLIST_EMPTY(&g_esp32_sessions[sid])) + { + return -EINVAL; + } + + session = &g_esp32_sessions[sid]; + + while (!SLIST_EMPTY(session)) + { + data = SLIST_FIRST(session); + switch (data->alg) + { + case CRYPTO_SHA1_HMAC: + case CRYPTO_SHA2_256_HMAC: + axf = data->hw_axf; + if (data->hw_ictx) + { + explicit_bzero(data->hw_ictx, axf->ctxsize); + kmm_free(data->hw_ictx); + } + + if (data->hw_octx) + { + explicit_bzero(data->hw_octx, axf->ctxsize); + kmm_free(data->hw_octx); + } + + break; + } + + SLIST_REMOVE_HEAD(session, next); + kmm_free(data); + } + + return 0; +} + +/**************************************************************************** + * Name: esp32_process + * + * Description: + * process session to use hardware algorithm. + * + * Input Parameters: + * crp - The description of the crypto operation + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +static int esp32_process(struct cryptop *crp) +{ + struct cryptodesc *crd; + struct esp32_crypto_list *session; + struct esp32_crypto_data *data; + uint8_t iv[AESCTR_BLOCKSIZE]; + uint32_t lid; + int err = 0; + lid = crp->crp_sid & 0xffffffff; + + /* Go through crypto descriptors, processing as we go */ + + session = &g_esp32_sessions[lid]; + for (crd = crp->crp_desc; crd; crd = crd->crd_next) + { + SLIST_FOREACH(data, session, next) + { + if (data->alg == crd->crd_alg) + { + break; + } + } + + if (data == NULL) + { + crp->crp_etype = EINVAL; + return -EINVAL; + } + + switch (data->alg) + { + case CRYPTO_SHA1: + case CRYPTO_SHA2_256: + case CRYPTO_SHA2_384: + case CRYPTO_SHA2_512: + if ((crp->crp_etype = hash(crp, crd, data, + crp->crp_buf)) != 0) + { + return 0; + } + + break; + default: + return -EINVAL; + } + } + + return OK; +} + +/**************************************************************************** + * Name: hwcr_init + * + * Description: + * register the hardware crypto driver. + * + ****************************************************************************/ + +void hwcr_init(void) +{ + int hwcr_id; + int algs[CRYPTO_ALGORITHM_MAX + 1]; + + hwcr_id = crypto_get_driverid(0); + DEBUGASSERT(hwcr_id >= 0); + + memset(algs, 0, sizeof(algs)); + + algs[CRYPTO_SHA1] = CRYPTO_ALG_FLAG_SUPPORTED; + algs[CRYPTO_SHA2_256] = CRYPTO_ALG_FLAG_SUPPORTED; + algs[CRYPTO_SHA2_384] = CRYPTO_ALG_FLAG_SUPPORTED; + algs[CRYPTO_SHA2_512] = CRYPTO_ALG_FLAG_SUPPORTED; + + esp32_sha_init(); + crypto_register(hwcr_id, algs, esp32_newsession, + esp32_freesession, esp32_process); +} diff --git a/arch/xtensa/src/esp32/esp32_sha.c b/arch/xtensa/src/esp32/esp32_sha.c new file mode 100644 index 0000000000..6e2caf0697 --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_sha.c @@ -0,0 +1,399 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_sha.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#ifdef CONFIG_ESP32_SHA_ACCELERATOR + +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <inttypes.h> +#include <debug.h> +#include <nuttx/mutex.h> + +#include "xtensa.h" + +#include "hal/sha_hal.h" +#include "periph_ctrl.h" + +#include "esp32_sha.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static bool g_sha_inited; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_sha_block + * + * Description: + * Performs SHA on multiple blocks at a time. + * + * Input Parameters: + * ctx - The SHA context + * data - Input message to be hashed on single block + * len - Length of the input message on single block + * buf - Input message to be hashed on multiple blocks + * buf_len - Length of the input message on multiple blocks + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +static int esp32_sha_block(struct esp32_sha_context_s *ctx, + const unsigned char *buffer) +{ + sha_hal_hash_block(ctx->mode, (const void *)buffer, + ctx->block_size / 32, ctx->first_block); + + ctx->first_block = false; + sha_hal_wait_idle(); + if (ctx->final_block) + { + sha_hal_read_digest(ctx->mode, ctx->state); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_sha1_starts + * + * Description: + * Starts a SHA-1 checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp32_sha1_starts(struct esp32_sha_context_s *ctx) +{ + memset(ctx, 0, sizeof(struct esp32_sha_context_s)); + ctx->mode = ESP32_SHA1_1; + ctx->output_size = 160; + ctx->block_size = 512; + + return OK; +} + +/**************************************************************************** + * Name: esp32_sha_update + * + * Description: + * Feeds an input buffer into an ongoing SHA checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to use + * input - The buffer holding the input data + * ilen - The length of the input data in Bytes + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp32_sha_update(struct esp32_sha_context_s *ctx, + const unsigned char *input, + size_t ilen) +{ + unsigned int i; + unsigned int j; + + j = (uint32_t)((ctx->count[0] >> 3) & ((ctx->block_size >> 3) - 1)); + ctx->count[0] += (ilen << 3); + if (ctx->count[0] < (ilen << 3)) + { + if (ctx->mode == ESP32_SHA1_1 || ctx->mode == ESP32_SHA2_256) + return ERROR; + + ctx->count[1]++; + } + + if ((j + ilen) > ((ctx->block_size >> 3) - 1)) + { + memcpy(&ctx->buffer[j], input, (i = (ctx->block_size >> 3) - j)); + if (ctx->sha_state == ESP32_SHA_STATE_INIT) + { + ctx->first_block = true; + ctx->sha_state = ESP32_SHA_STATE_IN_PROCESS; + } + else if (ctx->sha_state == ESP32_SHA_STATE_IN_PROCESS) + { + ctx->first_block = false; + } + + esp32_sha_block(ctx, ctx->buffer); + for (; i + ((ctx->block_size >> 3) - 1) < ilen; + i += (ctx->block_size >> 3)) + esp32_sha_block(ctx, &input[i]); + + j = 0; + } + else + { + i = 0; + } + + memcpy(&ctx->buffer[j], &input[i], ilen - i); + return OK; +} + +/**************************************************************************** + * Name: esp32_sha_finish + * + * Description: + * Finishes the SHA operation, + * and writes the result to the output buffer. + * + * Input Parameters: + * ctx - The SHA context to use + * output - The SHA-1 checksum result + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp32_sha_finish(struct esp32_sha_context_s *ctx, + unsigned char output[64]) +{ + uint32_t aux; + unsigned int i; + unsigned char finalcount[16]; + + if (ctx->mode == ESP32_SHA1_1 || ctx->mode == ESP32_SHA2_256) + for (i = 0; i < 8; i++) + finalcount[i] = (unsigned char)((ctx->count[0] >> + ((8 - 1 - i) * 8)) & 255); + + /* SHA384 and SHA512 use 1024 bits to store the message length */ + + else + { + for (i = 0; i < 8; i++) + finalcount[i] = (unsigned char)((ctx->count[1] >> + ((8 - 1 - i) * 8)) & 255); + for (i = 8; i < 16; i++) + finalcount[i] = (unsigned char)((ctx->count[0] >> + ((16 - 1 - i) * 8)) & 255); + } + + esp32_sha_update(ctx, (unsigned char *)"\200", 1); + + while ((ctx->count[0] & (ctx->block_size - 8)) != + ctx->block_size - (ctx->block_size >> 3)) + esp32_sha_update(ctx, (unsigned char *)"\0", 1); + + ctx->final_block = true; + + if (ctx->mode == ESP32_SHA1_1 || ctx->mode == ESP32_SHA2_256) + esp32_sha_update(ctx, finalcount, 8); + + /* SHA384 and SHA512 use 1024 bits to store the message length */ + + else + esp32_sha_update(ctx, finalcount, 16); + + if (ctx->mode == ESP32_SHA3_384 || ctx->mode == ESP32_SHA3_512) + { + /* For these ciphers swap each pair of words */ + + for (i = 0; i < ctx->output_size / 32; i += 2) + { + aux = ctx->state[i + 1]; + ctx->state[i + 1] = ctx->state[i]; + ctx->state[i] = aux; + } + } + + for (i = 0; i < ctx->output_size / 8; i++) + { + output[i] = (unsigned char)((ctx->state[i >> 2] >> + ((3 - (i & 3)) * 8)) & 255); + } + + explicit_bzero(&finalcount, sizeof(finalcount)); + explicit_bzero(ctx, sizeof(*ctx)); + + return 0; +} + +/**************************************************************************** + * Name: esp32_sha1_free + * + * Description: + * Clears a SHA context. + * + * Input Parameters: + * ctx - The SHA context to clear + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32_sha1_free(struct esp32_sha_context_s *ctx) +{ + if (ctx == NULL) + return; + + memset(ctx, 0, sizeof(struct esp32_sha_context_s)); +} + +/**************************************************************************** + * Name: esp32_sha256_starts + * + * Description: + * Starts a SHA-256 checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp32_sha256_starts(struct esp32_sha_context_s *ctx) +{ + memset(ctx, 0, sizeof(struct esp32_sha_context_s)); + ctx->mode = ESP32_SHA2_256; + ctx->output_size = 256; + ctx->block_size = 512; + + return OK; +} + +/**************************************************************************** + * Name: esp32_sha384_starts + * + * Description: + * Starts a SHA-384 checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp32_sha384_starts(struct esp32_sha_context_s *ctx) +{ + memset(ctx, 0, sizeof(struct esp32_sha_context_s)); + ctx->mode = ESP32_SHA3_384; + ctx->output_size = 384; + ctx->block_size = 1024; + + return OK; +} + +/**************************************************************************** + * Name: esp32_sha512_starts + * + * Description: + * Starts a SHA-512 checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp32_sha512_starts(struct esp32_sha_context_s *ctx) +{ + memset(ctx, 0, sizeof(struct esp32_sha_context_s)); + ctx->mode = ESP32_SHA3_512; + ctx->output_size = 512; + ctx->block_size = 1024; + + return OK; +} + +/**************************************************************************** + * Name: esp32_sha_init + * + * Description: + * Initialize ESP32 SHA hardware. + * + * Input Parameters: + * None + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp32_sha_init(void) +{ + if (!g_sha_inited) + { + periph_module_enable(PERIPH_SHA_MODULE); + g_sha_inited = true; + } + else + { + return -EBUSY; + } + + return OK; +} + +#endif + diff --git a/arch/xtensa/src/esp32/esp32_sha.h b/arch/xtensa/src/esp32/esp32_sha.h new file mode 100644 index 0000000000..8e7b491385 --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_sha.h @@ -0,0 +1,226 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_sha.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_SHA_H +#define __ARCH_XTENSA_SRC_ESP32_ESP32_SHA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <nuttx/config.h> +#include <stdint.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum esp32_sha_type_e +{ + ESP32_SHA1_1 = 0, + ESP32_SHA2_256, + ESP32_SHA3_384, + ESP32_SHA3_512, + ESP32_SHA_TYPE_MAX +}; + +enum esp32_sha_state_e +{ + ESP32_SHA_STATE_INIT, + ESP32_SHA_STATE_IN_PROCESS +}; + +/* SHA context structure */ + +struct esp32_sha_context_s +{ + uint64_t count[2]; /* number of bits processed */ + uint32_t state[16]; /* intermediate digest state */ + bool final_block; + unsigned char buffer[128]; /* data block being processed */ + bool first_block; /* if first then true else false */ + uint16_t output_size; + uint16_t block_size; + enum esp32_sha_type_e mode; + enum esp32_sha_state_e sha_state; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_sha_init + * + * Description: + * Initialize ESP32 SHA hardware. + * + * Input Parameters: + * None + * + * Returned Value: + * OK is returned on success. Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp32_sha_init(void); + +/**************************************************************************** + * Name: esp32_sha1_init + * + * Description: + * Initializes a SHA context. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32_sha1_init(struct esp32_sha_context_s *ctx); + +/**************************************************************************** + * Name: esp32_sha1_starts + * + * Description: + * Starts a SHA checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp32_sha1_starts(struct esp32_sha_context_s *ctx); + +/**************************************************************************** + * Name: esp32_sha_update + * + * Description: + * Feeds an input buffer into an ongoing SHA checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to use + * input - The buffer holding the input data + * ilen - The length of the input data in Bytes + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp32_sha_update(struct esp32_sha_context_s *ctx, + const unsigned char *input, + size_t ilen); + +/**************************************************************************** + * Name: esp32_sha_finish + * + * Description: + * Finishes the SHA operation, + * and writes the result to the output buffer. + * + * Input Parameters: + * ctx - The SHA context to use + * output - The SHA checksum result + * + * Returned Value: + * OK is returned on success. + * Otherwise, a negated errno value is returned. + * + ****************************************************************************/ + +int esp32_sha_finish(struct esp32_sha_context_s *ctx, + unsigned char output[64]); + +/**************************************************************************** + * Name: esp32_sha256_starts + * + * Description: + * Starts a SHA-256 checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp32_sha256_starts(struct esp32_sha_context_s *ctx); + +/**************************************************************************** + * Name: esp32_sha384_starts + * + * Description: + * Starts a SHA-384 checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp32_sha384_starts(struct esp32_sha_context_s *ctx); + +/**************************************************************************** + * Name: esp32_sha512_starts + * + * Description: + * Starts a SHA-512 checksum calculation. + * + * Input Parameters: + * ctx - The SHA context to initialize + * + * Returned Value: + * OK is returned on success. + * + ****************************************************************************/ + +int esp32_sha512_starts(struct esp32_sha_context_s *ctx); + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_SHA_H */ diff --git a/arch/xtensa/src/esp32/hal.mk b/arch/xtensa/src/esp32/hal.mk index f7f712879e..10b3ea5c5e 100644 --- a/arch/xtensa/src/esp32/hal.mk +++ b/arch/xtensa/src/esp32/hal.mk @@ -128,8 +128,10 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)uart_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mmu_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)i2c_hal.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)sha_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)log_noos.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)log.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)dport_access_common.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)adc_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)gpio_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)ledc_periph.c diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/crypto/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/crypto/defconfig new file mode 100644 index 0000000000..600c1ac3e6 --- /dev/null +++ b/boards/xtensa/esp32/esp32-devkitc/configs/crypto/defconfig @@ -0,0 +1,57 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_LEDS is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ALLOW_BSD_COMPONENTS=y +CONFIG_ARCH="xtensa" +CONFIG_ARCH_BOARD="esp32-devkitc" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_ESP32_DEVKITC=y +CONFIG_ARCH_CHIP="esp32" +CONFIG_ARCH_CHIP_ESP32=y +CONFIG_ARCH_CHIP_ESP32WROVER=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH_XTENSA=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_CRYPTODEV=y +CONFIG_CRYPTO_CRYPTODEV_HARDWARE=y +CONFIG_CRYPTO_RANDOM_POOL=y +CONFIG_DEFAULT_TASK_STACKSIZE=8192 +CONFIG_ESP32_SHA_ACCELERATOR=y +CONFIG_ESP32_UART0=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=6096 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RAM_SIZE=314688 +CONFIG_RAM_START=0x20000000 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=3 +CONFIG_START_MONTH=5 +CONFIG_START_YEAR=2025 +CONFIG_SYSLOG_BUFFER=y +CONFIG_SYSTEM_NSH=y +CONFIG_TESTING_CRYPTO=y +CONFIG_TESTING_CRYPTO_HASH=y +CONFIG_UART0_SERIAL_CONSOLE=y