feat(mbedtls): adds SHA drivers with PSA

This commit is contained in:
Ashish Sharma
2025-12-19 07:27:59 +08:00
parent bf46351fb0
commit e629ab299c
20 changed files with 2128 additions and 55 deletions
+6 -3
View File
@@ -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()
+1 -1
View File
@@ -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.
@@ -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
@@ -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 <stdio.h>
#include <string.h>
#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;
}
@@ -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 <stdio.h>
#include <string.h>
#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;
}
@@ -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 <stdio.h>
#include <string.h>
#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;
}
@@ -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 <stdint.h>
#include <stddef.h>
/* 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 */
@@ -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 <stdint.h>
#include <stddef.h>
/* 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 */
@@ -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 <stdint.h>
#include <stddef.h>
/* 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 */
@@ -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 <string.h>
#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;
}
@@ -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 <string.h>
#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;
}
@@ -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 <string.h>
#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;
}
@@ -0,0 +1,283 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#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;
}
@@ -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 <stdbool.h>
#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
@@ -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 <stdint.h>
#include <stdbool.h>
#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 */
@@ -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}
+4 -4
View File
@@ -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
@@ -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
}
@@ -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) {
@@ -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 */
}