diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index be63f717866..aa927fc19bb 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -262,13 +262,13 @@ if(CONFIG_SOC_AES_SUPPORTED) endif() if(SHA_PERIPHERAL_TYPE STREQUAL "core") - target_include_directories(builtin PRIVATE "${COMPONENT_DIR}/port/sha/core/include") + target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/sha/core/include") if(CONFIG_SOC_SHA_GDMA) set(SHA_CORE_SRCS "${COMPONENT_DIR}/port/sha/core/esp_sha_gdma_impl.c") elseif(CONFIG_SOC_SHA_CRYPTO_DMA) set(SHA_CORE_SRCS "${COMPONENT_DIR}/port/sha/core/esp_sha_crypto_dma_impl.c") endif() - target_sources(builtin PRIVATE "${SHA_CORE_SRCS}") + target_sources(tfpsacrypto PRIVATE "${SHA_CORE_SRCS}") endif() if(AES_PERIPHERAL_TYPE STREQUAL "dma") @@ -318,11 +318,14 @@ if(CONFIG_SOC_SHA_SUPPORTED) # "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c" # ) if(CONFIG_MBEDTLS_HARDWARE_SHA) + target_compile_definitions(tfpsacrypto PRIVATE ESP_SHA_DRIVER_ENABLED) target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c" "${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha1.c" "${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha256.c" - "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c") + "${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha512.c" + "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c" + "${COMPONENT_DIR}/port/sha/esp_sha.c") endif() endif() diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 853f3e30135..780ae657771 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -1487,7 +1487,7 @@ menu "mbedTLS" config MBEDTLS_HARDWARE_SHA bool "Enable hardware SHA acceleration" - default n + default y depends on !SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST && SOC_SHA_SUPPORTED help Enable hardware accelerated SHA1, SHA256, SHA384 & SHA512 in mbedTLS. diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index b1877969f23..aba8c436135 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -197,11 +197,11 @@ #ifdef CONFIG_MBEDTLS_HARDWARE_SHA #define MBEDTLS_SHA1_ALT #define MBEDTLS_SHA256_ALT -#define ESP_SHA_DRIVER_ENABLED #define MBEDTLS_PSA_ACCEL_ALG_SHA_1 -// TODO: Implement SHA224 #define MBEDTLS_PSA_ACCEL_ALG_SHA_224 #define MBEDTLS_PSA_ACCEL_ALG_SHA_256 +#define MBEDTLS_PSA_ACCEL_ALG_SHA_384 +#define MBEDTLS_PSA_ACCEL_ALG_SHA_512 #if SOC_SHA_SUPPORT_SHA512 #define MBEDTLS_SHA512_ALT #else diff --git a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c new file mode 100644 index 00000000000..a7b7f54ffcb --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c @@ -0,0 +1,217 @@ +/* + * SHA-1 implementation with hardware ESP support added. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include +#include "mbedtls/esp_config.h" +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha1.h" +#include "esp_sha_internal.h" +#include "sha/sha_core.h" +#include "esp_err.h" + +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 +}; + +static int esp_sha1_starts(esp_sha1_context *ctx) { + memset(ctx, 0, sizeof(esp_sha1_context)); + return ESP_OK; +} + +static void esp_internal_sha1_block_process(esp_sha1_context *ctx, const uint8_t *data) +{ + esp_sha_block(SHA1, data, ctx->first_block); + + if (ctx->first_block) { + ctx->first_block = false; + } +} + +static void esp_internal_sha_update_state(esp_sha1_context *ctx) +{ + 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); + } +} + +static int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t ilen) +{ + size_t fill, left, len; + uint32_t 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 = SHA_ALIGN_DOWN(ilen , 64); + + if (len || local_len) { + + esp_sha_acquire_hardware(); + + esp_sha_set_mode(SHA1); + + esp_internal_sha_update_state(ctx); + +#if SOC_SHA_SUPPORT_DMA + if (sha_operation_mode(len) == SHA_DMA_MODE) { + int ret = esp_sha_dma(SHA1, input, len, ctx->buffer, local_len, ctx->first_block); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + } else +#endif /* SOC_SHA_SUPPORT_DMA */ + { + /* First process buffered block, if any */ + if (local_len) { + esp_internal_sha1_block_process(ctx, ctx->buffer); + } + + uint32_t length_processed = 0; + while (len - length_processed != 0) { + esp_internal_sha1_block_process(ctx, input + length_processed); + length_processed += 64; + } + } + + esp_sha_read_digest_state(SHA1, ctx->state); + + esp_sha_release_hardware(); + + } + + if (ilen > 0) { + memcpy((void *) (ctx->buffer + left), input + len, ilen - len); + } + return 0; +} + +static int esp_sha1_finish(esp_sha1_context *ctx, uint8_t *hash) +{ + int ret = -1; + 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 = esp_sha1_update(ctx, sha1_padding, padn)) != 0) { + return ret; + } + if ((ret = esp_sha1_update(ctx, msglen, 8)) != 0) { + return ret; + } + + memcpy(hash, ctx->state, 20); + + return ret; +} + +psa_status_t esp_sha1_driver_compute( + esp_sha1_context *ctx, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + if (ctx == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha1_starts(ctx); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha1_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha1_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_1); + return PSA_SUCCESS; +} + +psa_status_t esp_sha1_driver_update( + esp_sha1_context *ctx, + const uint8_t *input, + size_t input_length) +{ + if (ctx == NULL || input == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha1_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + return PSA_SUCCESS; +} + +psa_status_t esp_sha1_driver_finish( + esp_sha1_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + if (ctx == NULL || hash == NULL || hash_length == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha1_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_1); + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c new file mode 100644 index 00000000000..9904eb220bf --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c @@ -0,0 +1,244 @@ +/* + * SHA-256 implementation with hardware ESP support added. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include +#include "mbedtls/esp_config.h" +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha256.h" +#include "esp_sha_internal.h" +#include "sha/sha_core.h" +#include "esp_err.h" + +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 +}; + +static int esp_sha256_starts(esp_sha256_context *ctx, int mode) { + memset(ctx, 0, sizeof(esp_sha256_context)); + ctx->mode = mode; /* SHA2_224 or SHA2_256 */ + return ESP_OK; +} + +static void esp_internal_sha256_block_process(esp_sha256_context *ctx, const uint8_t *data) +{ + esp_sha_block(ctx->mode, data, ctx->first_block); + + if (ctx->first_block) { + ctx->first_block = false; + } +} + +static void esp_internal_sha_update_state(esp_sha256_context *ctx) +{ + 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); + } +} + +static int esp_sha256_update(esp_sha256_context *ctx, const unsigned char *input, + size_t ilen) +{ + size_t fill, left, len; + uint32_t local_len = 0; + + if (ilen == 0 || 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]++; + } + + /* 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 = SHA_ALIGN_DOWN(ilen , 64); + + if (len || local_len) { + + esp_sha_acquire_hardware(); + + esp_sha_set_mode(ctx->mode); + + esp_internal_sha_update_state(ctx); + +#if SOC_SHA_SUPPORT_DMA + if (sha_operation_mode(len) == SHA_DMA_MODE) { + int ret = esp_sha_dma(ctx->mode, input, len, ctx->buffer, local_len, ctx->first_block); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + } else +#endif /* SOC_SHA_SUPPORT_DMA */ + { + /* First process buffered block, if any */ + if (local_len) { + esp_internal_sha256_block_process(ctx, ctx->buffer); + } + + uint32_t length_processed = 0; + while (len - length_processed != 0) { + esp_internal_sha256_block_process(ctx, input + length_processed); + length_processed += 64; + } + } + + esp_sha_read_digest_state(ctx->mode, ctx->state); + + esp_sha_release_hardware(); + } + + if (ilen > 0) { + memcpy((void *) (ctx->buffer + left), input + len, ilen - len); + } + + return 0; +} + +static int esp_sha256_finish(esp_sha256_context *ctx, unsigned char *output) +{ + int ret = -1; + 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 = esp_sha256_update(ctx, sha256_padding, padn)) != 0) { + return ret; + } + + if ((ret = esp_sha256_update(ctx, msglen, 8)) != 0) { + return ret; + } + + if (ctx->mode == SHA2_224) { + memcpy(output, ctx->state, 28); + } else { + memcpy(output, ctx->state, 32); + } + + return 0; +} + + +psa_status_t esp_sha256_driver_compute( + esp_sha256_context *ctx, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + printf("SHA256 Driver Compute\n"); + if (!hash || !hash_length) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (alg != PSA_ALG_SHA_256 && alg != PSA_ALG_SHA_224) { + return PSA_ERROR_NOT_SUPPORTED; + } + if (hash_size < PSA_HASH_LENGTH(alg)) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + int mode = (alg == PSA_ALG_SHA_224) ? SHA2_224 : SHA2_256; + int ret = esp_sha256_starts(ctx, mode); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha256_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha256_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + *hash_length = PSA_HASH_LENGTH(alg); + return PSA_SUCCESS; +} + +psa_status_t esp_sha256_driver_update( + esp_sha256_context *ctx, + const uint8_t *input, + size_t input_length) +{ + if (ctx == NULL || input == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha256_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + return PSA_SUCCESS; +} + +psa_status_t esp_sha256_driver_finish( + esp_sha256_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length, + esp_sha_operation_type_t sha_type) +{ + if (ctx == NULL || hash == NULL || hash_length == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha256_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + if (sha_type == ESP_SHA_OPERATION_TYPE_SHA224) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_224); + } else if (sha_type == ESP_SHA_OPERATION_TYPE_SHA256) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_256); + } else { + return PSA_ERROR_NOT_SUPPORTED; + } + if (hash_size < *hash_length) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c new file mode 100644 index 00000000000..f0501efecdb --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c @@ -0,0 +1,273 @@ +/* + * SHA-512 implementation with hardware ESP support added. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include +#include "mbedtls/esp_config.h" +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha512.h" +#include "esp_sha_internal.h" +#include "sha/sha_core.h" +#include "esp_err.h" + +#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 */ + +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 +}; + +static int esp_sha512_starts(esp_sha512_context *ctx, int mode) { + memset(ctx, 0, sizeof(esp_sha512_context)); + ctx->mode = mode; + return ESP_OK; +} + +static int esp_internal_sha_update_state(esp_sha512_context *ctx) +{ + if (ctx->sha_state == ESP_SHA512_STATE_INIT) { + if (ctx->mode == SHA2_512T) { + int ret = -1; + if ((ret = esp_sha_512_t_init_hash(ctx->t_val)) != 0) { + return ret; + } + 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); + } + return 0; +} + +static void esp_internal_sha512_block_process(esp_sha512_context *ctx, const uint8_t *data) +{ + esp_sha_block(ctx->mode, data, ctx->first_block); + + if (ctx->first_block) { + ctx->first_block = false; + } +} + +static int esp_sha512_update(esp_sha512_context *ctx, const unsigned char *input, + size_t ilen) +{ + size_t fill, left, len; + uint32_t local_len = 0; + + if (ilen == 0) { + return 0; + } + + left = (size_t) (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 = SHA_ALIGN_DOWN(ilen , 128); + + if (len || local_len) { + + esp_sha_acquire_hardware(); + + esp_sha_set_mode(ctx->mode); + + int ret = esp_internal_sha_update_state(ctx); + + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + +#if SOC_SHA_SUPPORT_DMA + if (sha_operation_mode(len) == SHA_DMA_MODE) { + ret = esp_sha_dma(ctx->mode, input, len, ctx->buffer, local_len, ctx->first_block); + if (ret != 0) { + esp_sha_release_hardware(); + return ret; + } + } else +#endif /* SOC_SHA_SUPPORT_DMA */ + { + /* First process buffered block, if any */ + if (local_len) { + esp_internal_sha512_block_process(ctx, ctx->buffer); + } + + uint32_t length_processed = 0; + while (len - length_processed != 0) { + esp_internal_sha512_block_process(ctx, input + length_processed); + length_processed += 128; + } + } + + esp_sha_read_digest_state(ctx->mode, ctx->state); + + esp_sha_release_hardware(); + } + + if (ilen > 0) { + memcpy((void *) (ctx->buffer + left), input + len, ilen - len); + } + + return 0; +} + +static int esp_sha512_finish(esp_sha512_context *ctx, unsigned char *output) +{ + int ret = -1; + 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 = esp_sha512_update(ctx, sha512_padding, padn)) != 0) { + return ret; + } + + if ((ret = esp_sha512_update(ctx, msglen, 16)) != 0) { + return ret; + } + + if (ctx->mode == SHA2_384) { + memcpy(output, ctx->state, 48); + } else { + memcpy(output, ctx->state, 64); + } + + return ret; +} + +psa_status_t esp_sha512_driver_compute( + esp_sha512_context *ctx, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + printf("SHA512 Driver Compute\n"); + if (!hash || !hash_length) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (alg != PSA_ALG_SHA_512 && alg != PSA_ALG_SHA_384) { + return PSA_ERROR_NOT_SUPPORTED; + } + if (hash_size < PSA_HASH_LENGTH(alg)) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + int mode = (alg == PSA_ALG_SHA_384) ? SHA2_384 : SHA2_512; + int ret = esp_sha512_starts(ctx, mode); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha512_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha512_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + *hash_length = PSA_HASH_LENGTH(alg); + return PSA_SUCCESS; +} + +psa_status_t esp_sha512_driver_update( + esp_sha512_context *ctx, + const uint8_t *input, + size_t input_length) +{ + if (ctx == NULL || input == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha512_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + return PSA_SUCCESS; +} + +psa_status_t esp_sha512_driver_finish( + esp_sha512_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length, + esp_sha_operation_type_t sha_type) +{ + if (ctx == NULL || hash == NULL || hash_length == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha512_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + if (sha_type == ESP_SHA_OPERATION_TYPE_SHA384) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_384); + } else if (sha_type == ESP_SHA_OPERATION_TYPE_SHA512) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_512); + } else { + return PSA_ERROR_NOT_SUPPORTED; + } + if (hash_size < *hash_length) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha1.h b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha1.h new file mode 100644 index 00000000000..74686abb530 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha1.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#pragma once + +#if defined(ESP_SHA_DRIVER_ENABLED) + +#include +#include + +/* Forward declarations to avoid circular dependencies */ +// typedef struct esp_sha1_context esp_sha1_context; +typedef uint32_t psa_algorithm_t; +typedef int32_t psa_status_t; + +psa_status_t esp_sha1_driver_compute( + esp_sha1_context *ctx, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +psa_status_t esp_sha1_driver_update( + esp_sha1_context *ctx, + const uint8_t *input, + size_t input_length); + +psa_status_t esp_sha1_driver_finish( + esp_sha1_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); +#endif /* ESP_SHA_DRIVER_ENABLED */ diff --git a/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha256.h b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha256.h new file mode 100644 index 00000000000..0464aadebea --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha256.h @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#pragma once + +#if defined(ESP_SHA_DRIVER_ENABLED) + +#include +#include + +/* Forward declarations to avoid circular dependencies */ +// typedef struct esp_sha256_context esp_sha256_context; +typedef uint32_t psa_algorithm_t; +typedef int32_t psa_status_t; + +psa_status_t esp_sha256_driver_compute( + esp_sha256_context *ctx, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +psa_status_t esp_sha256_driver_update( + esp_sha256_context *ctx, + const uint8_t *input, + size_t input_length); + +psa_status_t esp_sha256_driver_finish( + esp_sha256_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length, + esp_sha_operation_type_t sha_type); +#endif /* ESP_SHA_DRIVER_ENABLED */ diff --git a/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha512.h b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha512.h new file mode 100644 index 00000000000..703f469ef9c --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha512.h @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#pragma once + +#if defined(ESP_SHA_DRIVER_ENABLED) + +#include +#include + +/* Forward declarations to avoid circular dependencies */ +// typedef struct esp_sha256_context esp_sha256_context; +typedef uint32_t psa_algorithm_t; +typedef int32_t psa_status_t; + +psa_status_t esp_sha512_driver_compute( + esp_sha512_context *ctx, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +psa_status_t esp_sha512_driver_update( + esp_sha512_context *ctx, + const uint8_t *input, + size_t input_length); + +psa_status_t esp_sha512_driver_finish( + esp_sha512_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length, + esp_sha_operation_type_t sha_type); +#endif /* ESP_SHA_DRIVER_ENABLED */ diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c new file mode 100644 index 00000000000..85773e73310 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c @@ -0,0 +1,228 @@ +/* + * SHA-1 implementation with hardware ESP support added. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha1.h" +#include "sha/sha_parallel_engine.h" +#include "esp_err.h" + +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 +}; + +static int esp_sha1_starts(esp_sha1_context *ctx) { + memset(ctx, 0, sizeof(esp_sha1_context)); + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; + // esp_sha_unlock_engine(SHA1); + ctx->sha_state = ESP_SHA1_STATE_INIT; + return ESP_OK; +} + +// static void esp_internal_sha_update_state(esp_sha1_context *ctx) +// { +// 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); +// } +// } + +static int esp_internal_sha1_parallel_engine_process( esp_sha1_context *ctx, const unsigned char data[64], bool read_digest ) +{ + if (ctx->sha_state == ESP_SHA1_STATE_INIT) { + if (esp_sha_try_lock_engine(SHA1)) { + printf("Got the SHA1 engine lock\n"); + ctx->first_block = true; + ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS; + } else { + printf("Failed to lock SHA1 engine\n"); + return -1; + } + } else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) { + // printf("SHA1 in process\n"); + ctx->first_block = false; + } + esp_sha_block(SHA1, data, ctx->first_block); + if (read_digest) { + esp_sha_read_digest_state(SHA1, ctx->state); + } + + return 0; +} + +static int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t ilen) +{ + int ret = -1; + size_t fill; + uint32_t left; + + 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]++; + } + + if ( left && ilen >= fill ) { + memcpy( (void *) (ctx->buffer + left), input, fill ); + + if ( ( ret = esp_internal_sha1_parallel_engine_process( ctx, ctx->buffer, false ) ) != 0 ) { + return ret; + } + + input += fill; + ilen -= fill; + left = 0; + } + + while ( ilen >= 64 ) { + if ( ( ret = esp_internal_sha1_parallel_engine_process( ctx, input, false ) ) != 0 ) { + return ret; + } + + input += 64; + ilen -= 64; + } + + if ( ilen > 0 ) { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } + + return 0; +} + +psa_status_t esp_sha1_driver_update( + esp_sha1_context *ctx, + const uint8_t *input, + size_t input_length) +{ + if (ctx == NULL || input == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha1_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + return PSA_SUCCESS; +} + +static int esp_sha1_finish(esp_sha1_context *ctx, uint8_t *output) +{ + int ret = -1; + 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 = esp_sha1_update(ctx, sha1_padding, padn)) != 0) { + goto out; + } + if ((ret = esp_sha1_update(ctx, msglen, 8)) != 0) { + goto out; + } + + if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) { + // If there is no more input data, and state is in hardware, read it out to ctx->state + // This ensures that ctx->state always has the latest digest state + esp_sha_read_digest_state(SHA1, ctx->state); + } + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); + +out: + esp_sha_unlock_engine(SHA1); + + return ret; +} + +psa_status_t esp_sha1_driver_finish( + esp_sha1_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + if (ctx == NULL || hash == NULL || hash_length == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha1_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_1); + return PSA_SUCCESS; +} + +psa_status_t esp_sha1_driver_compute( + esp_sha1_context *ctx, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + if (ctx == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha1_starts(ctx); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha1_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha1_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_1); + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c new file mode 100644 index 00000000000..95199faab8b --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c @@ -0,0 +1,262 @@ +/* + * SHA-1 implementation with hardware ESP support added. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha256.h" +#include "sha/sha_parallel_engine.h" +#include "esp_err.h" + +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 +}; + +static void esp_internal_sha_update_state(esp_sha1_context *ctx) +{ + 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(SHA1, ctx->state); + } +} + +static int esp_internal_sha256_parallel_engine_process( esp_sha256_context *ctx, const unsigned char data[64], bool read_digest ) +{ + if (ctx->sha_state == ESP_SHA256_STATE_INIT) { + if (esp_sha_try_lock_engine(SHA2_256)) { + printf("Got the SHA2_256 engine lock\n"); + ctx->first_block = true; + ctx->sha_state = ESP_SHA256_STATE_IN_PROCESS; + } else { + printf("Failed to lock SHA2_256 engine\n"); + return -1; + } + } else if (ctx->sha_state == ESP_SHA256_STATE_IN_PROCESS) { + // printf("SHA1 in process\n"); + ctx->first_block = false; + } + esp_sha_block(SHA2_256, data, ctx->first_block); + if (read_digest) { + esp_sha_read_digest_state(SHA2_256, ctx->state); + } + + return 0; +} + +static int esp_sha256_update(esp_sha256_context *ctx, const unsigned char *input, + size_t ilen) +{ + int ret = -1; + size_t fill; + uint32_t left; + + 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]++; + } + + if ( left && ilen >= fill ) { + memcpy( (void *) (ctx->buffer + left), input, fill ); + + if ( ( ret = esp_internal_sha256_parallel_engine_process( ctx, ctx->buffer, false ) ) != 0 ) { + return ret; + } + + input += fill; + ilen -= fill; + left = 0; + } + + while ( ilen >= 64 ) { + if ( ( ret = esp_internal_sha256_parallel_engine_process( ctx, input, false ) ) != 0 ) { + return ret; + } + + input += 64; + ilen -= 64; + } + + // esp_sha_read_digest_state(SHA2_256, ctx->state); + + + if ( ilen > 0 ) { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } + + return 0; +} + +psa_status_t esp_sha256_driver_update( + esp_sha256_context *ctx, + const uint8_t *input, + size_t input_length) +{ + if (ctx == NULL || input == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha256_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + return PSA_SUCCESS; +} + +static int esp_sha256_starts( esp_sha256_context *ctx, int is224 ) +{ + memset( ctx, 0, sizeof( esp_sha256_context ) ); + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; + + // esp_sha_unlock_engine(SHA2_256); + ctx->sha_state = ESP_SHA256_STATE_INIT; + return 0; +} + +static int esp_sha256_finish(esp_sha256_context *ctx, unsigned char *output) +{ + int ret = -1; + 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 = esp_sha256_update( ctx, sha256_padding, padn ) ) != 0 ) { + goto out; + } + + if ( ( ret = esp_sha256_update( ctx, msglen, 8 ) ) != 0 ) { + goto out; + } + + esp_sha_read_digest_state(SHA2_256, ctx->state); + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); + PUT_UINT32_BE( ctx->state[5], output, 20 ); + PUT_UINT32_BE( ctx->state[6], output, 24 ); + + PUT_UINT32_BE( ctx->state[7], output, 28 ); + + +out: + esp_sha_unlock_engine(SHA2_256); + return ret; +} + +psa_status_t esp_sha256_driver_compute( + esp_sha256_context *ctx, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + if (!hash || !hash_length) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (alg != PSA_ALG_SHA_256 +#if SOC_SHA_SUPPORT_SHA224 + && alg != PSA_ALG_SHA_224 +#endif // SOC_SHA_SUPPORT_SHA224 + ) { + return PSA_ERROR_NOT_SUPPORTED; + } + if (hash_size < PSA_HASH_LENGTH(alg)) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } +#if SOC_SHA_SUPPORT_SHA224 + int mode = (alg == PSA_ALG_SHA_224) ? SHA2_224 : SHA2_256; +#else + int mode = SHA2_256; +#endif // SOC_SHA_SUPPORT_SHA224 + int ret = esp_sha256_starts(ctx, mode); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha256_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha256_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + *hash_length = PSA_HASH_LENGTH(alg); + return PSA_SUCCESS; +} + +psa_status_t esp_sha256_driver_finish( + esp_sha256_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length, + esp_sha_operation_type_t sha_type) +{ + if (ctx == NULL || hash == NULL || hash_length == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha256_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + if (sha_type == ESP_SHA_OPERATION_TYPE_SHA224) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_224); + } else if (sha_type == ESP_SHA_OPERATION_TYPE_SHA256) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_256); + } else { + return PSA_ERROR_NOT_SUPPORTED; + } + if (hash_size < *hash_length) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c new file mode 100644 index 00000000000..132cef51df3 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c @@ -0,0 +1,308 @@ +/* + * SHA-1 implementation with hardware ESP support added. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha512.h" +#include "sha/sha_parallel_engine.h" +#include "esp_err.h" + +#if defined(_MSC_VER) || defined(__WATCOMC__) +#define UL64(x) x##ui64 +#else +#define UL64(x) x##ULL +#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 +}; + +#ifndef GET_UINT64_BE +#define GET_UINT64_BE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ + | ( (uint64_t) (b)[(i) + 1] << 48 ) \ + | ( (uint64_t) (b)[(i) + 2] << 40 ) \ + | ( (uint64_t) (b)[(i) + 3] << 32 ) \ + | ( (uint64_t) (b)[(i) + 4] << 24 ) \ + | ( (uint64_t) (b)[(i) + 5] << 16 ) \ + | ( (uint64_t) (b)[(i) + 6] << 8 ) \ + | ( (uint64_t) (b)[(i) + 7] ); \ +} +#endif /* GET_UINT64_BE */ + +#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 */ + +inline static esp_sha_type sha_type(const esp_sha512_context *ctx) +{ + return ctx->mode; +} + +static int esp_internal_sha512_parallel_engine_process( esp_sha512_context *ctx, const unsigned char data[128], bool read_digest ) +{ + if (ctx->sha_state == ESP_SHA512_STATE_INIT) { + if (esp_sha_try_lock_engine(SHA2_512)) { + printf("Got the SHA512 engine lock\n"); + ctx->first_block = true; + ctx->sha_state = ESP_SHA512_STATE_IN_PROCESS; + } else { + printf("Failed to lock SHA512 engine\n"); + return -1; + } + } else if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) { + // printf("SHA512 in process\n"); + ctx->first_block = false; + } + esp_sha_block(sha_type(ctx), data, ctx->first_block); + if (read_digest) { + esp_sha_read_digest_state(sha_type(ctx), ctx->state); + } + + return 0; +} + +static int esp_sha512_update(esp_sha512_context *ctx, const unsigned char *input, + size_t ilen) +{ + int ret = -1; + size_t fill; + unsigned int left; + + 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 ); + if ( ( ret = esp_internal_sha512_parallel_engine_process( ctx, ctx->buffer, false ) ) != 0 ) { + return ret; + } + + input += fill; + ilen -= fill; + left = 0; + } + + while ( ilen >= 128 ) { + if ( ( ret = esp_internal_sha512_parallel_engine_process( ctx, input, false ) ) != 0 ) { + return ret; + } + + input += 128; + ilen -= 128; + } + + // esp_sha_read_digest_state(sha_type(ctx), ctx->state); + + if ( ilen > 0 ) { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } + + return 0; +} + +static int esp_sha512_starts( esp_sha512_context *ctx, int mode ) +{ + memset( ctx, 0, sizeof( esp_sha512_context ) ); + ctx->total[0] = 0; + ctx->total[1] = 0; + + if ( mode == SHA2_512 ) { + /* SHA-512 */ + ctx->state[0] = UL64(0x6A09E667F3BCC908); + ctx->state[1] = UL64(0xBB67AE8584CAA73B); + ctx->state[2] = UL64(0x3C6EF372FE94F82B); + ctx->state[3] = UL64(0xA54FF53A5F1D36F1); + ctx->state[4] = UL64(0x510E527FADE682D1); + ctx->state[5] = UL64(0x9B05688C2B3E6C1F); + ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); + ctx->state[7] = UL64(0x5BE0CD19137E2179); + } else { + /* SHA-384 */ + printf("SHA-384 Init\n"); + ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); + ctx->state[1] = UL64(0x629A292A367CD507); + ctx->state[2] = UL64(0x9159015A3070DD17); + ctx->state[3] = UL64(0x152FECD8F70E5939); + ctx->state[4] = UL64(0x67332667FFC00B31); + ctx->state[5] = UL64(0x8EB44A8768581511); + ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); + ctx->state[7] = UL64(0x47B5481DBEFA4FA4); + } + + ctx->mode = mode; + // esp_sha_unlock_engine(sha_type(ctx)); + ctx->sha_state = ESP_SHA512_STATE_INIT; + + return 0; +} + +static int esp_sha512_finish(esp_sha512_context *ctx, unsigned char *output) +{ + int ret = -1; + 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 = esp_sha512_update( ctx, sha512_padding, padn ) ) != 0 ) { + goto out; + } + + if ( ( ret = esp_sha512_update( ctx, msglen, 16 ) ) != 0 ) { + goto out; + } + + if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) { + // If there is no more input data, and state is in hardware, read it out to ctx->state + // This ensures that ctx->state always has the latest digest state + esp_sha_read_digest_state(SHA2_512, ctx->state); + ctx->sha_state = ESP_SHA512_STATE_INIT; + } + + PUT_UINT64_BE( ctx->state[0], output, 0 ); + PUT_UINT64_BE( ctx->state[1], output, 8 ); + PUT_UINT64_BE( ctx->state[2], output, 16 ); + PUT_UINT64_BE( ctx->state[3], output, 24 ); + PUT_UINT64_BE( ctx->state[4], output, 32 ); + PUT_UINT64_BE( ctx->state[5], output, 40 ); + + if ( ctx->mode == SHA2_512 ) { + PUT_UINT64_BE( ctx->state[6], output, 48 ); + PUT_UINT64_BE( ctx->state[7], output, 56 ); + } + +out: + printf("Releasing SHA512 engine lock\n"); + esp_sha_unlock_engine(sha_type(ctx)); + + return ret; +} + +psa_status_t esp_sha512_driver_compute( + esp_sha512_context *ctx, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + printf("SHA512 Driver Compute\n"); + if (!hash || !hash_length) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (alg != PSA_ALG_SHA_512 && alg != PSA_ALG_SHA_384) { + return PSA_ERROR_NOT_SUPPORTED; + } + if (hash_size < PSA_HASH_LENGTH(alg)) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + int mode = (alg == PSA_ALG_SHA_384) ? SHA2_384 : SHA2_512; + int ret = esp_sha512_starts(ctx, mode); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha512_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + ret = esp_sha512_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + *hash_length = PSA_HASH_LENGTH(alg); + return PSA_SUCCESS; +} + +psa_status_t esp_sha512_driver_update( + esp_sha512_context *ctx, + const uint8_t *input, + size_t input_length) +{ + if (ctx == NULL || input == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha512_update(ctx, input, input_length); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + + return PSA_SUCCESS; +} + +psa_status_t esp_sha512_driver_finish( + esp_sha512_context *ctx, + uint8_t *hash, + size_t hash_size, + size_t *hash_length, + esp_sha_operation_type_t sha_type) +{ + if (ctx == NULL || hash == NULL || hash_length == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + int ret = esp_sha512_finish(ctx, hash); + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + if (sha_type == ESP_SHA_OPERATION_TYPE_SHA384) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_384); + } else if (sha_type == ESP_SHA_OPERATION_TYPE_SHA512) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_512); + } else { + return PSA_ERROR_NOT_SUPPORTED; + } + if (hash_size < *hash_length) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c new file mode 100644 index 00000000000..075d6ba4be0 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c @@ -0,0 +1,283 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "mbedtls/esp_config.h" +#include "psa_crypto_driver_esp_sha.h" +#include "include/psa_crypto_driver_esp_sha1.h" +#include "include/psa_crypto_driver_esp_sha256.h" +#include "include/psa_crypto_driver_esp_sha512.h" +#include "psa/crypto.h" +#include "psa/crypto_sizes.h" +#include "esp_log.h" + +#if CONFIG_SOC_SHA_GDMA +#include "esp_sha_internal.h" +#endif +#include "sha/sha_core.h" + +#include "esp_err.h" + +static int esp_sha_driver_check_supported_algorithm(psa_algorithm_t alg) { + if (alg == PSA_ALG_SHA_1 || alg == PSA_ALG_SHA_256 || alg == PSA_ALG_SHA_224 || + alg == PSA_ALG_SHA_512 || alg == PSA_ALG_SHA_384) { + return ESP_OK; + } + return ESP_ERR_NOT_SUPPORTED; +} + +static int esp_sha_validate_args(psa_algorithm_t alg, const uint8_t *input, size_t input_length, uint8_t *hash, size_t hash_size) { + if (!input || !hash) { + return ESP_ERR_INVALID_ARG; + } + + size_t expected_hash_size = PSA_HASH_LENGTH(alg); + if (hash_size < expected_hash_size) { + return ESP_ERR_INVALID_SIZE; + } + + return ESP_OK; +} + +psa_status_t esp_sha_hash_compute( + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + int ret = esp_sha_driver_check_supported_algorithm(alg); + if (ret != ESP_OK) { + return PSA_ERROR_NOT_SUPPORTED; + } + + ret = esp_sha_validate_args(alg, input, input_length, hash, hash_size); + if (ret == ESP_ERR_INVALID_ARG) { + return PSA_ERROR_INVALID_ARGUMENT; + } else if (ret == ESP_ERR_INVALID_SIZE) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } else if (ret != ESP_OK) { + return PSA_ERROR_GENERIC_ERROR; + } + + size_t hash_length_calculated = 0; + switch(alg) { +#if CONFIG_SOC_SHA_SUPPORT_SHA1 + case PSA_ALG_SHA_1: + esp_sha1_context sha1_ctx = {0}; + ret = esp_sha1_driver_compute(&sha1_ctx, input, input_length, hash, hash_size, &hash_length_calculated); + memset(&sha1_ctx, 0, sizeof(sha1_ctx)); + *hash_length = hash_length_calculated; + break; +#endif // CONFIG_SOC_SHA_SUPPORT_SHA1 +#if CONFIG_SOC_SHA_SUPPORT_SHA224 + case PSA_ALG_SHA_224: +#endif // CONFIG_SOC_SHA_SUPPORT_SHA224 +#if CONFIG_SOC_SHA_SUPPORT_SHA256 + case PSA_ALG_SHA_256: + esp_sha256_context sha256_ctx = {0}; + ret = esp_sha256_driver_compute(&sha256_ctx, alg, input, input_length, hash, hash_size, &hash_length_calculated); + memset(&sha256_ctx, 0, sizeof(sha256_ctx)); + *hash_length = hash_length_calculated; + break; +#endif // CONFIG_SOC_SHA_SUPPORT_SHA256 +#if CONFIG_SOC_SHA_SUPPORT_SHA384 + case PSA_ALG_SHA_384: +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 +#if CONFIG_SOC_SHA_SUPPORT_SHA512 + case PSA_ALG_SHA_512: + esp_sha512_context sha512_ctx = {0}; + ret = esp_sha512_driver_compute(&sha512_ctx, alg, input, input_length, hash, hash_size, &hash_length_calculated); + memset(&sha512_ctx, 0, sizeof(sha512_ctx)); + *hash_length = hash_length_calculated; + break; +#endif // CONFIG_SOC_SHA_SUPPORT_SHA512 + default: + return PSA_ERROR_NOT_SUPPORTED; + } + + if (ret != ESP_OK) { + return PSA_ERROR_HARDWARE_FAILURE; + } + return PSA_SUCCESS; +} + +psa_status_t esp_sha_hash_setup(esp_sha_hash_operation_t *operation, psa_algorithm_t alg) +{ + if (!operation) { + return PSA_ERROR_INVALID_ARGUMENT; + } +#if CONFIG_SOC_SHA_SUPPORT_SHA1 + if (alg == PSA_ALG_SHA_1) { + esp_sha1_context *sha1_ctx = calloc(1, sizeof(esp_sha1_context)); + operation->sha_ctx = sha1_ctx; + operation->sha_type = ESP_SHA_OPERATION_TYPE_SHA1; + return PSA_SUCCESS; + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA1 +#if CONFIG_SOC_SHA_SUPPORT_SHA256 + if ( +#if CONFIG_SOC_SHA_SUPPORT_SHA224 + alg == PSA_ALG_SHA_224 || +#endif // CONFIG_SOC_SHA_SUPPORT_SHA224 + alg == PSA_ALG_SHA_256) { + esp_sha256_context *sha256_ctx = calloc(1, sizeof(esp_sha256_context)); + operation->sha_ctx = sha256_ctx; + sha256_ctx->mode = SHA2_256; + operation->sha_type = ESP_SHA_OPERATION_TYPE_SHA256; +#if CONFIG_SOC_SHA_SUPPORT_SHA224 + operation->sha_type = (alg == PSA_ALG_SHA_224) ? ESP_SHA_OPERATION_TYPE_SHA224 : ESP_SHA_OPERATION_TYPE_SHA256; + sha256_ctx->mode = (alg == PSA_ALG_SHA_224) ? SHA2_224 : SHA2_256; +#endif // CONFIG_SOC_SHA_SUPPORT_SHA224 + return PSA_SUCCESS; + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA256 +#if CONFIG_SOC_SHA_SUPPORT_SHA512 + if ( +#if CONFIG_SOC_SHA_SUPPORT_SHA384 + alg == PSA_ALG_SHA_384 || +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 + alg == PSA_ALG_SHA_512) { + esp_sha512_context *sha512_ctx = calloc(1, sizeof(esp_sha512_context)); + operation->sha_ctx = sha512_ctx; + sha512_ctx->mode = SHA2_512; + operation->sha_type = ESP_SHA_OPERATION_TYPE_SHA512; +#if CONFIG_SOC_SHA_SUPPORT_SHA384 + operation->sha_type = (alg == PSA_ALG_SHA_384) ? ESP_SHA_OPERATION_TYPE_SHA384 : ESP_SHA_OPERATION_TYPE_SHA512; + sha512_ctx->mode = (alg == PSA_ALG_SHA_384) ? SHA2_384 : SHA2_512; +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 + return PSA_SUCCESS; + } +#endif // CONFIG_SOC_SHA_SUPPORT_SHA512 + return PSA_ERROR_NOT_SUPPORTED; +} + +psa_status_t esp_sha_hash_update( + esp_sha_hash_operation_t *operation, + const uint8_t *input, + size_t input_length) +{ + if (!operation || !operation->sha_ctx || !input) { + return PSA_ERROR_INVALID_ARGUMENT; + } +#if CONFIG_SOC_SHA_SUPPORT_SHA1 + if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) { + esp_sha1_context *ctx = (esp_sha1_context *)operation->sha_ctx; + return esp_sha1_driver_update(ctx, input, input_length); + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA1 +#if CONFIG_SOC_SHA_SUPPORT_SHA224 || CONFIG_SOC_SHA_SUPPORT_SHA256 + if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA256 || operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) { + esp_sha256_context *ctx = (esp_sha256_context *)operation->sha_ctx; + return esp_sha256_driver_update(ctx, input, input_length); + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA224 || CONFIG_SOC_SHA_SUPPORT_SHA256 +#if CONFIG_SOC_SHA_SUPPORT_SHA384 || CONFIG_SOC_SHA_SUPPORT_SHA512 + if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA384 || operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) { + esp_sha512_context *ctx = (esp_sha512_context *)operation->sha_ctx; + return esp_sha512_driver_update(ctx, input, input_length); + } +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 || CONFIG_SOC_SHA_SUPPORT_SHA512 + return PSA_ERROR_NOT_SUPPORTED; +} + +psa_status_t esp_sha_hash_finish( + esp_sha_hash_operation_t *operation, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + if (!operation || !hash || !hash_length) { + return PSA_ERROR_INVALID_ARGUMENT; + } + +#if CONFIG_SOC_SHA_SUPPORT_SHA1 + if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) { + esp_sha1_context *ctx = (esp_sha1_context *)operation->sha_ctx; + int ret = esp_sha1_driver_finish(ctx, hash, hash_size, hash_length); + free(ctx); // Free the context after use + operation->sha_ctx = NULL; + return ret; + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA1 +#if CONFIG_SOC_SHA_SUPPORT_SHA224 || CONFIG_SOC_SHA_SUPPORT_SHA256 + if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA256 || + operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) { + esp_sha256_context *ctx = (esp_sha256_context *)operation->sha_ctx; + int ret = esp_sha256_driver_finish(ctx, hash, hash_size, hash_length, operation->sha_type); + free(ctx); // Free the context after use + operation->sha_ctx = NULL; + return ret; + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA224 || CONFIG_SOC_SHA_SUPPORT_SHA256 +#if CONFIG_SOC_SHA_SUPPORT_SHA384 || CONFIG_SOC_SHA_SUPPORT_SHA512 + if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA384 || + operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) { + esp_sha512_context *ctx = (esp_sha512_context *)operation->sha_ctx; + int ret = esp_sha512_driver_finish(ctx, hash, hash_size, hash_length, operation->sha_type); + free(ctx); // Free the context after use + operation->sha_ctx = NULL; + return ret; + } +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 || CONFIG_SOC_SHA_SUPPORT_SHA512 + + return PSA_ERROR_NOT_SUPPORTED; +} + +psa_status_t esp_sha_hash_abort(esp_sha_hash_operation_t *operation) +{ + if (!operation) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (operation->sha_ctx) { + free(operation->sha_ctx); + operation->sha_ctx = NULL; + } + + return PSA_SUCCESS; +} + +psa_status_t esp_sha_hash_clone( + const esp_sha_hash_operation_t *source_operation, + esp_sha_hash_operation_t *target_operation) +{ + target_operation->sha_type = source_operation->sha_type; +#if CONFIG_SOC_SHA_SUPPORT_SHA1 + if (target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) { + target_operation->sha_ctx = calloc(1, sizeof(esp_sha1_context)); + if (!target_operation->sha_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memcpy(target_operation->sha_ctx, source_operation->sha_ctx, sizeof(esp_sha1_context)); + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA1 +#if CONFIG_SOC_SHA_SUPPORT_SHA224 || CONFIG_SOC_SHA_SUPPORT_SHA256 + if (target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA256 || + target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA224) { + target_operation->sha_ctx = calloc(1, sizeof(esp_sha256_context)); + if (!target_operation->sha_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memcpy(target_operation->sha_ctx, source_operation->sha_ctx, sizeof(esp_sha256_context)); + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA224 || CONFIG_SOC_SHA_SUPPORT_SHA256 +#if CONFIG_SOC_SHA_SUPPORT_SHA384 || CONFIG_SOC_SHA_SUPPORT_SHA512 + if (target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA384 || + target_operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA512) { + target_operation->sha_ctx = calloc(1, sizeof(esp_sha512_context)); + if (!target_operation->sha_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memcpy(target_operation->sha_ctx, source_operation->sha_ctx, sizeof(esp_sha512_context)); + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 || CONFIG_SOC_SHA_SUPPORT_SHA512 + { + return PSA_ERROR_NOT_SUPPORTED; + } + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h new file mode 100644 index 00000000000..3de8382e4ac --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#if defined(ESP_SHA_DRIVER_ENABLED) +#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#endif + +#include +#include "psa_crypto_driver_esp_sha_contexts.h" +#include "psa/crypto.h" + +// /* Include function declarations from individual SHA modules */ +// #ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1 +// #include "../esp_sha/include/psa_crypto_driver_esp_sha1.h" +// #endif /* MBEDTLS_PSA_ACCEL_ALG_SHA_1 */ + +// #ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_256 +// #include "../esp_sha/include/psa_crypto_driver_esp_sha256.h" +// #endif + +#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 + +psa_status_t esp_sha_hash_compute( + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +psa_status_t esp_sha_hash_setup(esp_sha_hash_operation_t *operation, + psa_algorithm_t alg); + +psa_status_t esp_sha_hash_update( + esp_sha_hash_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t esp_sha_hash_finish( + esp_sha_hash_operation_t *operation, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +psa_status_t esp_sha_hash_abort(esp_sha_hash_operation_t *operation); + +psa_status_t esp_sha_hash_clone( + const esp_sha_hash_operation_t *source_operation, + esp_sha_hash_operation_t *target_operation); +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h new file mode 100644 index 00000000000..82780202bb3 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/** + * \file psa_crypto_driver_esp_sha_contexts.h + * + * \brief Context structure definitions for ESP SHA hardware driver. + * + * This file contains the context structures used by the ESP SHA driver + * for PSA Crypto API. These definitions are completely standalone and + * do not include any PSA Crypto headers to avoid circular dependencies. + * + * \note This file may not be included directly. It is included by + * crypto_driver_contexts_primitives.h. + */ + +#include +#include + +#if defined(ESP_SHA_DRIVER_ENABLED) + +typedef enum { + ESP_SHA_OPERATION_TYPE_SHA1, + ESP_SHA_OPERATION_TYPE_SHA256, + ESP_SHA_OPERATION_TYPE_SHA224, + ESP_SHA_OPERATION_TYPE_SHA512, + ESP_SHA_OPERATION_TYPE_SHA384 +} esp_sha_operation_type_t; + +/** + * \brief ESP SHA1 state enumeration + */ +typedef enum { + ESP_SHA1_STATE_INIT, + ESP_SHA1_STATE_IN_PROCESS +} esp_sha1_state; + +typedef enum { + ESP_SHA256_STATE_INIT, + ESP_SHA256_STATE_IN_PROCESS +} esp_sha256_state; + +typedef enum { + ESP_SHA512_STATE_INIT, + ESP_SHA512_STATE_IN_PROCESS +} esp_sha512_state; + +/** + * \brief ESP SHA1 context structure + */ +typedef struct { + uint32_t total[2]; /*!< The number of Bytes processed. */ + uint32_t state[5]; /*!< The intermediate digest state. */ + unsigned char buffer[64]; /*!< The data block being processed. */ + bool first_block; /*!< First block flag for hardware initialization */ + int sha_state; /*!< SHA operation state */ +} esp_sha1_context; + +/** + * \brief ESP SHA256 context structure + */ +typedef struct { + unsigned char buffer[64]; /*!< The data block being processed. */ + uint32_t total[2]; /*!< The number of Bytes processed. */ + uint32_t state[8]; /*!< The intermediate digest state. */ + bool first_block; /*!< First block flag for hardware initialization */ + int sha_state; /*!< SHA operation state */ + int mode; /*!< SHA2_224 or SHA2_256 */ +} esp_sha256_context; + +/** + * \brief ESP SHA512 context structure + * + */ +typedef struct { + uint64_t total[2]; /*!< The number of Bytes processed. */ + uint64_t state[8]; /*!< The intermediate digest state. */ + unsigned char buffer[128]; /*!< The data block being processed. */ + bool first_block; + int sha_state; + int mode; + uint32_t t_val; /*!< t_val for 512/t mode */ +} esp_sha512_context; + +typedef void *esp_sha_context_t; +/** + * \brief ESP SHA driver operation context + * + * This structure contains the contexts for different SHA algorithms + * supported by the ESP hardware accelerator. + */ +typedef struct { + esp_sha_context_t sha_ctx; + esp_sha_operation_type_t sha_type; +} esp_sha_hash_operation_t; + +#endif /* ESP_SHA_DRIVER_ENABLED */ diff --git a/components/mbedtls/test_apps/main/CMakeLists.txt b/components/mbedtls/test_apps/main/CMakeLists.txt index 40878758c4e..f467a3f64a4 100644 --- a/components/mbedtls/test_apps/main/CMakeLists.txt +++ b/components/mbedtls/test_apps/main/CMakeLists.txt @@ -7,7 +7,7 @@ set(TEST_CRTS "crts/server_cert_chain.pem" idf_component_register( # SRC_DIRS "." - SRCS "app_main.c" + SRCS "app_main.c" "test_sha.c" "test_sha_perf.c" "test_mbedtls_utils.c" PRIV_INCLUDE_DIRS "." PRIV_REQUIRES efuse cmock test_utils mbedtls esp_timer unity spi_flash esp_psram esp_security EMBED_TXTFILES ${TEST_CRTS} diff --git a/components/mbedtls/test_apps/main/test_sha.c b/components/mbedtls/test_apps/main/test_sha.c index 2da737394c3..70c9e302f1f 100644 --- a/components/mbedtls/test_apps/main/test_sha.c +++ b/components/mbedtls/test_apps/main/test_sha.c @@ -114,11 +114,11 @@ TEST_CASE("Test esp_sha()", "[hw_crypto]") // This check fails because it expects the hardware implementation to be available // and be faster than the software implementation - // TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA1_32KB, "%" PRId32 " us", us_sha1); + TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA1_32KB, "%" PRId32 " us", us_sha1); -// #if SOC_SHA_SUPPORT_SHA512 - // TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA512_32KB, "%" PRId32 " us", us_sha512); -// #endif +#if SOC_SHA_SUPPORT_SHA512 + TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA512_32KB, "%" PRId32 " us", us_sha512); +#endif } /* NOTE: This test attempts to mmap 1MB of flash starting from address 0x00, which overlaps diff --git a/components/mbedtls/test_apps/main/test_sha_perf.c b/components/mbedtls/test_apps/main/test_sha_perf.c index b156cbb3b90..6dbf82d7c83 100644 --- a/components/mbedtls/test_apps/main/test_sha_perf.c +++ b/components/mbedtls/test_apps/main/test_sha_perf.c @@ -18,31 +18,36 @@ #include "test_utils.h" #include "ccomp_timer.h" #include "test_mbedtls_utils.h" +#include "psa/crypto.h" TEST_CASE("mbedtls SHA performance", "[mbedtls]") { const unsigned CALLS = 256; const unsigned CALL_SZ = 16 * 1024; - mbedtls_sha256_context sha256_ctx; float elapsed_usec; unsigned char sha256[32]; + + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&operation, PSA_ALG_SHA_256); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + // allocate internal memory uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); TEST_ASSERT_NOT_NULL(buf); memset(buf, 0x55, CALL_SZ); - mbedtls_sha256_init(&sha256_ctx); ccomp_timer_start(); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false)); for (int c = 0; c < CALLS; c++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, buf, CALL_SZ)); + status = psa_hash_update(&operation, buf, CALL_SZ); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); } - TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256)); + size_t hash_length; + status = psa_hash_finish(&operation, sha256, sizeof(sha256), &hash_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); elapsed_usec = ccomp_timer_stop(); free(buf); - mbedtls_sha256_free(&sha256_ctx); /* Check the result. Reference value can be calculated using: * dd if=/dev/zero bs=$((16*1024)) count=256 | tr '\000' '\125' | sha256sum @@ -56,8 +61,8 @@ TEST_CASE("mbedtls SHA performance", "[mbedtls]") // bytes/usec = MB/sec float mb_sec = (CALL_SZ * CALLS) / elapsed_usec; printf("SHA256 rate %.3fMB/sec\n", mb_sec); -// #ifdef CONFIG_MBEDTLS_HARDWARE_SHA -// // Don't put a hard limit on software SHA performance -// TEST_PERFORMANCE_CCOMP_GREATER_THAN(SHA256_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec); -// #endif +#ifdef CONFIG_MBEDTLS_HARDWARE_SHA + // Don't put a hard limit on software SHA performance + TEST_PERFORMANCE_CCOMP_GREATER_THAN(SHA256_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec); +#endif } diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c index e9cd719cc34..f1f72646c2c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c @@ -262,22 +262,6 @@ int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, goto cleanup; } - size_t output_len = 0; - status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, in, inlen, NULL, 0, out, *outlen, &output_len); - if (status != PSA_SUCCESS) { - printf("Failed to decrypt data, returned %d", (int) status); - ret = -1; - goto cleanup; - } - *outlen = output_len; - - ret = mbedtls_pk_import_into_psa(pkey, &attributes, &key_id); - if (ret != 0) { - wpa_printf(MSG_ERROR, "failed to import key into PSA"); - ret = -1; - goto cleanup; - } - size_t output_len = 0; size_t heap_free_before = esp_get_free_heap_size(); status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, in, inlen, NULL, 0, out, *outlen, &output_len); @@ -289,7 +273,7 @@ int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, size_t heap_free_after = esp_get_free_heap_size(); printf("Heap free before: %d, Heap free after: %d, used: %d\n", heap_free_before, heap_free_after, heap_free_before - heap_free_after); *outlen = output_len; - + cleanup: psa_reset_key_attributes(&key_attributes); if (key_id) { diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpsk.c b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpsk.c index fb1a43ecd12..ed9a629910b 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpsk.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpsk.c @@ -322,21 +322,6 @@ int esp_fast_psk(const char *password, size_t password_len, const uint8_t *ssid, /* Compute the full PSK */ psa_status_t status; psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - - // Set up key attributes for password - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&attributes, PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_1)); - psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE); - - // Import password as key - status = psa_import_key(&attributes, (uint8_t*)password, password_len, &key_id); - if (status != PSA_SUCCESS) { - printf("Failed to import key: %d\n", status); - psa_reset_key_attributes(&attributes); - return -1; - } // Set up key derivation status = psa_key_derivation_setup(&operation, PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_1)); @@ -377,8 +362,6 @@ int esp_fast_psk(const char *password, size_t password_len, const uint8_t *ssid, cleanup: psa_key_derivation_abort(&operation); - psa_destroy_key(key_id); - psa_reset_key_attributes(&attributes); return 0; /* Success */ }