fix: migrate PSA SHA driver to be similar to parallel engine port

This commit is contained in:
Ashish Sharma
2025-12-19 11:06:41 +08:00
parent 646c9a994a
commit 5d5ba9d008
33 changed files with 761 additions and 246 deletions
@@ -252,11 +252,7 @@ bootloader_sha_handle_t bootloader_sha512_start(bool is384)
op->psa_alg = is384 ? PSA_ALG_SHA_384 : PSA_ALG_SHA_512;
*op->hash_op = psa_hash_operation_init();
if (is384) {
status = psa_hash_setup(op->hash_op, op->psa_alg);
} else {
status = psa_hash_setup(op->hash_op, op->psa_alg);
}
status = psa_hash_setup(op->hash_op, op->psa_alg);
if (status != PSA_SUCCESS) {
free(op->hash_op);
free(op);
@@ -52,7 +52,8 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl
#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS
case ECDSA_CURVE_P384:
key_size = 48;
mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP384R1);
curve_family = PSA_ECC_FAMILY_SECP_R1;
psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size));
break;
#endif /* CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS */
default:
@@ -64,22 +65,25 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve_family));
/* Prepare the public key data from X and Y coordinates */
uint8_t public_key[2 * ECDSA_INTEGER_LEN];
uint8_t public_key[(2 * ECDSA_INTEGER_LEN) + 1];
uint8_t x_point[ECDSA_INTEGER_LEN] = {0};
uint8_t y_point[ECDSA_INTEGER_LEN] = {0};
/* Convert key points from little-endian to big-endian format */
for (int i = 0; i < key_size; i++) {
x_point[i] = trusted_block->ecdsa.key.point[key_size - i - 1];
y_point[i] = trusted_block->ecdsa.key.point[2 * key_size - i - 1];
}
public_key[0] = 0x04; /* Uncompressed point format */
/* Combine X and Y into a single public key buffer */
memcpy(public_key, x_point, key_size);
memcpy(public_key + key_size, y_point, key_size);
memcpy(public_key + 1, x_point, key_size);
memcpy(public_key + 1 + key_size, y_point, key_size);
/* Import the public key */
status = psa_import_key(&key_attributes, public_key, 2 * key_size, &key_handle);
status = psa_import_key(&key_attributes, public_key, (2 * key_size) + 1, &key_handle);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to import key, err:%d", status);
ret = ESP_FAIL;
@@ -8,6 +8,7 @@
#include "psa/crypto.h"
#include "mbedtls/asn1.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/x509.h"
#include "secure_boot_signature_priv.h"
@@ -28,7 +29,7 @@ static int encode_rsa_pubkey_der(const uint8_t *modulus, size_t modulus_len,
uint8_t **der_start, size_t *der_len)
{
if (!der_buf || !der_start || !der_len || der_buf_size == 0) {
return -1;
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
int ret;
@@ -17,7 +17,7 @@ extern "C" {
#if (BLUFI_INCLUDED == TRUE)
#define BTC_BLUFI_GREAT_VER 0x01 //Version + Subversion
#define BTC_BLUFI_SUB_VER 0x03 //Version + Subversion
#define BTC_BLUFI_SUB_VER 0x04 //Version + Subversion
#define BTC_BLUFI_VERSION ((BTC_BLUFI_GREAT_VER<<8)|BTC_BLUFI_SUB_VER) //Version + Subversion
typedef UINT8 tGATT_IF;
+2 -2
View File
@@ -1577,8 +1577,8 @@ static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key)
psa_reset_key_attributes(&key_attributes);
size_t olen = 0;
status = psa_export_public_key(key_id, public_key, 65, &olen);
if (status != PSA_SUCCESS || olen != 65) {
status = psa_export_public_key(key_id, public_key, BLE_PUB_KEY_LEN, &olen);
if (status != PSA_SUCCESS || olen != BLE_PUB_KEY_LEN) {
goto exit;
}
+2 -2
View File
@@ -1720,8 +1720,8 @@ static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key)
psa_reset_key_attributes(&key_attributes);
size_t olen = 0;
status = psa_export_public_key(key_id, public_key, 65, &olen);
if (status != PSA_SUCCESS || olen != 65) {
status = psa_export_public_key(key_id, public_key, BLE_PUB_KEY_LEN, &olen);
if (status != PSA_SUCCESS || olen != BLE_PUB_KEY_LEN) {
goto exit;
}
+1 -1
View File
@@ -27,7 +27,7 @@ menu "ESP-TLS"
config ESP_TLS_USE_DS_PERIPHERAL
bool "Use Digital Signature (DS) Peripheral with ESP-TLS"
depends on ESP_TLS_USING_MBEDTLS && SOC_DIG_SIGN_SUPPORTED
default n
default y
help
Enable use of the Digital Signature Peripheral for ESP-TLS.The DS peripheral
can only be used when it is appropriately configured for TLS.
+1
View File
@@ -22,6 +22,7 @@
#include "esp_check.h"
#include "soc/soc_caps.h"
#include "mbedtls/esp_mbedtls_dynamic.h"
#include "mbedtls/private/pk_private.h"
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
#include "mbedtls/ecp.h"
#include "ecdsa/ecdsa_alt.h"
@@ -8,10 +8,6 @@ set(EXTRA_COMPONENT_DIRS
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
set(COMPONENTS main)
list(APPEND sdkconfig_defaults
$ENV{IDF_PATH}/components/mbedtls/config/mbedtls_preset_bt.conf
${CMAKE_CURRENT_SOURCE_DIR}/mbedtls_preset_temperature_sensor_example.conf
)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
if($ENV{CI_PIPELINE_ID})
@@ -1,3 +0,0 @@
CONFIG_MBEDTLS_CIPHER_MODE_CBC=y
CONFIG_MBEDTLS_CIPHER_MODE_CTR=y
CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_SIZE=y
@@ -21,16 +21,30 @@ endif()
set(mbedtls_test_srcs_dir "${idf_path}/components/mbedtls/test_apps/main")
#AES
if(CONFIG_SOC_AES_SUPPORTED)
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_psa_aes.c"
"${mbedtls_test_srcs_dir}/test_psa_aes_gcm.c"
"${mbedtls_test_srcs_dir}/test_aes_perf.c"
)
endif()
# SHA
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_mbedtls_sha.c"
"${mbedtls_test_srcs_dir}/test_sha.c"
"${mbedtls_test_srcs_dir}/test_sha_perf.c")
if(CONFIG_SOC_SHA_SUPPORTED)
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_sha.c"
"${mbedtls_test_srcs_dir}/test_sha_perf.c")
endif()
# Mixed
if(CONFIG_SOC_AES_SUPPORTED AND CONFIG_SOC_SHA_SUPPORTED)
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes_sha_parallel.c")
endif()
#ECC
if(CONFIG_SOC_ECC_SUPPORTED)
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_ecp.c")
endif()
# Utility
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_apb_dport_access.c"
"${mbedtls_test_srcs_dir}/test_mbedtls_utils.c")
@@ -7,6 +7,7 @@
#include "esp_log.h"
#include "esp_heap_caps.h"
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
#include "psa/crypto.h"
#include "esp_tee.h"
@@ -14,7 +14,7 @@
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 1000
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 18000
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 21000
#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 700000
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 45000
#define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 1300000
+9 -3
View File
@@ -45,6 +45,8 @@ if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE)
list(APPEND mbedtls_include_dirs "esp_crt_bundle/include")
endif()
list(APPEND mbedtls_include_dirs "${COMPONENT_DIR}/port/psa_driver/include")
idf_component_register(SRCS "${mbedtls_srcs}"
INCLUDE_DIRS "${mbedtls_include_dirs}"
PRIV_REQUIRES "${priv_requires}"
@@ -139,6 +141,8 @@ if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE)
list(APPEND include_dirs "${COMPONENT_DIR}/esp_crt_bundle/include")
endif()
list(APPEND include_dirs "${COMPONENT_DIR}/port/psa_driver/include")
include_directories(${include_dirs})
# Needed to for mbedtls_rom includes to work from within mbedtls
@@ -187,7 +191,6 @@ target_include_directories(tfpsacrypto PUBLIC "port/include")
target_include_directories(tfpsacrypto PRIVATE "port/psa_crypto_storage/include")
if(CONFIG_MBEDTLS_HARDWARE_SHA OR CONFIG_MBEDTLS_HARDWARE_AES)
list(APPEND include_dirs "${COMPONENT_DIR}/port/psa_driver/include")
target_include_directories(tfpsacrypto PUBLIC "${COMPONENT_DIR}/port/psa_driver/include")
endif()
@@ -354,12 +357,15 @@ if(CONFIG_SOC_SHA_SUPPORTED)
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/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()
target_sources(tfpsacrypto PRIVATE
"${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha1.c"
"${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c"
)
endif()
if(CONFIG_SOC_DIG_SIGN_SUPPORTED)
+3
View File
@@ -23,6 +23,7 @@
#include "esp_crypto_periph_clk.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#include "mbedtls/platform_util.h"
#if SOC_AES_GDMA
#define AES_LOCK() esp_crypto_sha_aes_lock_acquire()
@@ -134,6 +135,7 @@ static int esp_aes_block(esp_aes_context *ctx, const void *input, void *output)
key write to hardware. Treat this as a fatal error and zero the output block.
*/
if (ctx->key_in_hardware != ctx->key_bytes) {
mbedtls_platform_zeroize(output, 16);
memset(output, 0, 16);
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
}
@@ -159,6 +161,7 @@ static int esp_aes_block(esp_aes_context *ctx, const void *input, void *output)
// calling zeroing functions to narrow the
// window for a double-fault of the abort step, here
memset(output, 0, 16);
mbedtls_platform_zeroize(output, 16);
abort();
}
+238 -2
View File
@@ -15,7 +15,6 @@
#include "esp_crypto_lock.h"
#include "esp_crypto_periph_clk.h"
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
// #include "mbedtls/error.h"
#include "mbedtls/private/ecdsa.h"
#include "mbedtls/private/pk_private.h"
#include "mbedtls/asn1.h"
@@ -24,6 +23,9 @@
#include "mbedtls/bignum.h"
#include "ecdsa/ecdsa_alt.h"
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
#include "pk_wrap.h"
#endif // CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
#include "esp_tee_sec_storage.h"
#endif
@@ -87,6 +89,46 @@
__attribute__((unused)) static const char *TAG = "ecdsa_alt";
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
/* Forward declaration of custom PK info structure for ESP hardware ECDSA */
extern const mbedtls_pk_info_t esp_ecdsa_pk_info;
#endif
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
/* Forward declarations for wrapped functions */
int __wrap_mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
/* Forward declaration for ASN.1 conversion helper */
static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s,
unsigned char *sig, size_t sig_size,
size_t *slen);
#endif
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
int __wrap_mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *r,
const mbedtls_mpi *s);
/* Forward declaration for hardware verify function */
static int esp_ecdsa_verify(mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *r,
const mbedtls_mpi *s);
#else
/* Forward declaration for software verify when hardware verify is disabled */
int __real_mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q,
const mbedtls_mpi *r,
const mbedtls_mpi *s);
#endif
#if SOC_ECDSA_SUPPORTED
/**
* @brief Check if the extracted efuse blocks are valid
@@ -386,7 +428,12 @@ int esp_ecdsa_privkey_load_pk_context(mbedtls_pk_context *key_ctx, int efuse_blk
}
mbedtls_pk_init(key_ctx);
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
/* Use our custom pk_info that routes to hardware ECDSA for signing and/or verification */
pk_info = &esp_ecdsa_pk_info;
#else
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
#endif
if (mbedtls_pk_setup(key_ctx, pk_info) != 0) {
return -1;
}
@@ -560,7 +607,7 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s
return 0;
}
#endif
#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN */
void esp_ecdsa_free_pk_context(mbedtls_pk_context *key_ctx)
{
@@ -580,6 +627,195 @@ void esp_ecdsa_free_pk_context(mbedtls_pk_context *key_ctx)
mbedtls_pk_free(key_ctx);
}
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
/* Custom PK wrapper functions for ESP hardware ECDSA
*
* Flow: mbedtls_pk_sign() → esp_ecdsa_pk_sign_wrap() → esp_ecdsa_sign() → Hardware ECDSA
*
* This bypasses the PSA opaque key path and routes directly to hardware ECDSA
* by using a custom pk_info structure that doesn't require PSA key IDs.
*/
static int esp_ecdsa_pk_can_do(mbedtls_pk_type_t type)
{
return type == MBEDTLS_PK_ECKEY ||
type == MBEDTLS_PK_ECDSA;
}
static size_t esp_ecdsa_pk_get_bitlen(mbedtls_pk_context *pk)
{
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*pk);
if (keypair == NULL) {
return 0;
}
return keypair->MBEDTLS_PRIVATE(grp).nbits;
}
#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY */
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
static int esp_ecdsa_pk_verify_wrap(mbedtls_pk_context *pk,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len)
{
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*pk);
int ret;
unsigned char *p = (unsigned char *) sig;
const unsigned char *end = sig + sig_len;
size_t len;
mbedtls_mpi r, s;
(void) md_alg; /* Not used for hardware ECDSA verification */
if (keypair == NULL) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* Check if public key is loaded */
if (mbedtls_mpi_cmp_int(&keypair->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 0) == 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
/* Parse the DER signature */
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
ret += MBEDTLS_ERR_PK_BAD_INPUT_DATA;
goto cleanup;
}
if (p + len != end) {
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
goto cleanup;
}
if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 ||
(ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0) {
ret += MBEDTLS_ERR_PK_BAD_INPUT_DATA;
goto cleanup;
}
/* Call verification function directly - wrapper doesn't work from same compilation unit */
ret = esp_ecdsa_verify(&keypair->MBEDTLS_PRIVATE(grp),
hash, hash_len,
&keypair->MBEDTLS_PRIVATE(Q),
&r, &s);
if (ret == 0 && p != end) {
ESP_LOGW(TAG, "Extra data after signature");
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
cleanup:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
return ret;
}
#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY */
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
static int esp_ecdsa_pk_sign_wrap(mbedtls_pk_context *pk,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t sig_size,
size_t *sig_len)
{
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*pk);
int ret;
mbedtls_mpi r, s;
(void) md_alg; /* Not used for hardware ECDSA signing */
if (keypair == NULL) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* Check if this is a hardware-backed key by checking the magic value */
signed short key_magic = keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s);
if (key_magic != ECDSA_KEY_MAGIC && key_magic != ECDSA_KEY_MAGIC_TEE) {
/* Not a hardware key, this shouldn't happen with our setup */
return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
}
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
/* Call esp_ecdsa_sign directly - wrapper doesn't work from same compilation unit */
ret = esp_ecdsa_sign(&keypair->MBEDTLS_PRIVATE(grp),
&r, &s,
&keypair->MBEDTLS_PRIVATE(d),
hash, hash_len,
ECDSA_K_TYPE_TRNG);
if (ret != 0) {
goto cleanup;
}
/* Convert r and s to DER format */
ret = ecdsa_signature_to_asn1(&r, &s, sig, sig_size, sig_len);
cleanup:
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
return ret;
}
#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN */
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
static int esp_ecdsa_pk_check_pair_wrap(mbedtls_pk_context *pub, mbedtls_pk_context *prv)
{
/* For hardware-backed keys, we cannot easily verify the pair
* since the private key never leaves the eFuse.
* We'll do a basic check that both contexts are valid. */
if (pub == NULL || prv == NULL) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
mbedtls_ecp_keypair *pub_keypair = mbedtls_pk_ec(*pub);
mbedtls_ecp_keypair *prv_keypair = mbedtls_pk_ec(*prv);
if (pub_keypair == NULL || prv_keypair == NULL) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
/* Check that both use the same curve */
if (pub_keypair->MBEDTLS_PRIVATE(grp).id != prv_keypair->MBEDTLS_PRIVATE(grp).id) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
return 0;
}
/* Custom pk_info structure for ESP hardware ECDSA */
const mbedtls_pk_info_t esp_ecdsa_pk_info = {
.type = MBEDTLS_PK_ECDSA,
.name = "ESP_ECDSA",
.get_bitlen = esp_ecdsa_pk_get_bitlen,
.can_do = esp_ecdsa_pk_can_do,
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
.verify_func = esp_ecdsa_pk_verify_wrap,
#else
.verify_func = NULL,
#endif
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
.sign_func = esp_ecdsa_pk_sign_wrap,
#else
.sign_func = NULL,
#endif
#if defined(MBEDTLS_ECP_RESTARTABLE)
.verify_rs_func = NULL,
.sign_rs_func = NULL,
.rs_alloc_func = NULL,
.rs_free_func = NULL,
#endif /* MBEDTLS_ECP_RESTARTABLE */
.check_pair_func = esp_ecdsa_pk_check_pair_wrap,
.ctx_alloc_func = NULL,
.ctx_free_func = NULL,
.debug_func = NULL,
};
#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY */
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, const char *tee_key_id)
{
@@ -60,6 +60,8 @@
*/
#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS
#define PSA_WANT_ECC_SECP_R1_192 1
/**
* \name SECTION: System support
*
@@ -17,6 +17,16 @@
#include "sha/sha_core.h"
#include "esp_err.h"
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
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,
@@ -29,6 +39,7 @@ int esp_sha1_starts(esp_sha1_context *ctx) {
return ESP_OK;
}
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
static void esp_internal_sha1_block_process(esp_sha1_context *ctx, const uint8_t *data)
{
esp_sha_block(SHA1, data, ctx->first_block);
@@ -49,6 +60,197 @@ static void esp_internal_sha_update_state(esp_sha1_context *ctx)
}
}
#else
static void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned char data[64] )
{
uint32_t temp, W[16], A, B, C, D, E;
GET_UINT32_BE( W[ 0], data, 0 );
GET_UINT32_BE( W[ 1], data, 4 );
GET_UINT32_BE( W[ 2], data, 8 );
GET_UINT32_BE( W[ 3], data, 12 );
GET_UINT32_BE( W[ 4], data, 16 );
GET_UINT32_BE( W[ 5], data, 20 );
GET_UINT32_BE( W[ 6], data, 24 );
GET_UINT32_BE( W[ 7], data, 28 );
GET_UINT32_BE( W[ 8], data, 32 );
GET_UINT32_BE( W[ 9], data, 36 );
GET_UINT32_BE( W[10], data, 40 );
GET_UINT32_BE( W[11], data, 44 );
GET_UINT32_BE( W[12], data, 48 );
GET_UINT32_BE( W[13], data, 52 );
GET_UINT32_BE( W[14], data, 56 );
GET_UINT32_BE( W[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define R(t) \
( \
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)
#define P(a,b,c,d,e,x) \
{ \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999
P( A, B, C, D, E, W[0] );
P( E, A, B, C, D, W[1] );
P( D, E, A, B, C, W[2] );
P( C, D, E, A, B, W[3] );
P( B, C, D, E, A, W[4] );
P( A, B, C, D, E, W[5] );
P( E, A, B, C, D, W[6] );
P( D, E, A, B, C, W[7] );
P( C, D, E, A, B, W[8] );
P( B, C, D, E, A, W[9] );
P( A, B, C, D, E, W[10] );
P( E, A, B, C, D, W[11] );
P( D, E, A, B, C, W[12] );
P( C, D, E, A, B, W[13] );
P( B, C, D, E, A, W[14] );
P( A, B, C, D, E, W[15] );
P( E, A, B, C, D, R(16) );
P( D, E, A, B, C, R(17) );
P( C, D, E, A, B, R(18) );
P( B, C, D, E, A, R(19) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1
P( A, B, C, D, E, R(20) );
P( E, A, B, C, D, R(21) );
P( D, E, A, B, C, R(22) );
P( C, D, E, A, B, R(23) );
P( B, C, D, E, A, R(24) );
P( A, B, C, D, E, R(25) );
P( E, A, B, C, D, R(26) );
P( D, E, A, B, C, R(27) );
P( C, D, E, A, B, R(28) );
P( B, C, D, E, A, R(29) );
P( A, B, C, D, E, R(30) );
P( E, A, B, C, D, R(31) );
P( D, E, A, B, C, R(32) );
P( C, D, E, A, B, R(33) );
P( B, C, D, E, A, R(34) );
P( A, B, C, D, E, R(35) );
P( E, A, B, C, D, R(36) );
P( D, E, A, B, C, R(37) );
P( C, D, E, A, B, R(38) );
P( B, C, D, E, A, R(39) );
#undef K
#undef F
#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC
P( A, B, C, D, E, R(40) );
P( E, A, B, C, D, R(41) );
P( D, E, A, B, C, R(42) );
P( C, D, E, A, B, R(43) );
P( B, C, D, E, A, R(44) );
P( A, B, C, D, E, R(45) );
P( E, A, B, C, D, R(46) );
P( D, E, A, B, C, R(47) );
P( C, D, E, A, B, R(48) );
P( B, C, D, E, A, R(49) );
P( A, B, C, D, E, R(50) );
P( E, A, B, C, D, R(51) );
P( D, E, A, B, C, R(52) );
P( C, D, E, A, B, R(53) );
P( B, C, D, E, A, R(54) );
P( A, B, C, D, E, R(55) );
P( E, A, B, C, D, R(56) );
P( D, E, A, B, C, R(57) );
P( C, D, E, A, B, R(58) );
P( B, C, D, E, A, R(59) );
#undef K
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6
P( A, B, C, D, E, R(60) );
P( E, A, B, C, D, R(61) );
P( D, E, A, B, C, R(62) );
P( C, D, E, A, B, R(63) );
P( B, C, D, E, A, R(64) );
P( A, B, C, D, E, R(65) );
P( E, A, B, C, D, R(66) );
P( D, E, A, B, C, R(67) );
P( C, D, E, A, B, R(68) );
P( B, C, D, E, A, R(69) );
P( A, B, C, D, E, R(70) );
P( E, A, B, C, D, R(71) );
P( D, E, A, B, C, R(72) );
P( C, D, E, A, B, R(73) );
P( B, C, D, E, A, R(74) );
P( A, B, C, D, E, R(75) );
P( E, A, B, C, D, R(76) );
P( D, E, A, B, C, R(77) );
P( C, D, E, A, B, R(78) );
P( B, C, D, E, A, R(79) );
#undef K
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
}
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
int esp_internal_sha1_process( esp_sha1_context *ctx, const unsigned char data[64] )
{
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
esp_sha_acquire_hardware();
esp_sha_set_mode(SHA1);
esp_internal_sha_update_state(ctx);
#if SOC_SHA_SUPPORT_DMA
// Unlikely to use DMA because data size is 64 bytes which is smaller than the DMA threshold
if (unlikely(sha_operation_mode(64) == SHA_DMA_MODE)) {
int ret = esp_sha_dma(SHA1, data, 64, NULL, 0, ctx->first_block);
if (ret != 0) {
esp_sha_release_hardware();
return ret;
}
} else
#endif /* SOC_SHA_SUPPORT_DMA */
{
esp_sha_block(SHA1, data, ctx->first_block);
}
esp_sha_read_digest_state(SHA1, ctx->state);
esp_sha_release_hardware();
#else
esp_sha1_software_process(ctx, data);
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
return 0;
}
int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t ilen)
{
size_t fill, left, len;
@@ -79,7 +281,7 @@ int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t il
len = SHA_ALIGN_DOWN(ilen , 64);
if (len || local_len) {
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
esp_sha_acquire_hardware();
esp_sha_set_mode(SHA1);
@@ -111,7 +313,9 @@ int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t il
esp_sha_read_digest_state(SHA1, ctx->state);
esp_sha_release_hardware();
#else
esp_sha1_software_process(ctx, input);
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
}
if (ilen > 0) {
@@ -7,8 +7,6 @@
#pragma once
#if defined(ESP_SHA_DRIVER_ENABLED)
#include <stdint.h>
#include <stddef.h>
@@ -41,4 +39,3 @@ psa_status_t esp_sha1_driver_finish(
psa_status_t esp_sha1_driver_abort(esp_sha1_context *ctx);
psa_status_t esp_sha1_driver_clone(const esp_sha1_context *source_ctx, esp_sha1_context *target_ctx);
#endif /* ESP_SHA_DRIVER_ENABLED */
@@ -34,12 +34,24 @@
}
#endif
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
};
psa_status_t esp_sha1_driver_clone(const esp_sha1_context *source_ctx, esp_sha1_context *target_ctx)
{
if (source_ctx == NULL || target_ctx == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(target_ctx, source_ctx, sizeof(esp_sha1_context));
// If the source context is in hardware mode, we need to read the digest state
// from the hardware engine to ensure the target context has the correct state
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
if (source_ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA1, target_ctx->state);
target_ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; // Cloned context operates in software mode
}
#else
target_ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; // Cloned context operates in software mode
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
return PSA_SUCCESS;
}
int esp_sha1_starts(esp_sha1_context *ctx)
{
@@ -53,13 +65,17 @@ int esp_sha1_starts(esp_sha1_context *ctx)
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
ctx->sha_state = ESP_SHA1_STATE_INIT;
ctx->first_block = false;
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_unlock_engine(SHA1);
}
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
ctx->operation_mode = ESP_SHA_MODE_UNUSED;
return ESP_OK;
}
void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned char data[64] )
static void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned char data[64] )
{
uint32_t temp, W[16], A, B, C, D, E;
@@ -217,31 +233,39 @@ void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned char data[
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) {
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
bool first_block = false;
if (ctx->operation_mode == ESP_SHA_MODE_UNUSED) {
/* try to use hardware for this digest */
if (esp_sha_try_lock_engine(SHA1)) {
ctx->first_block = true;
ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
ctx->operation_mode = ESP_SHA_MODE_HARDWARE;
first_block = true;
} else {
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
}
} else if (ctx->sha_state == ESP_SHA1_STATE_IN_PROCESS) {
ctx->first_block = false;
}
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_block(SHA1, data, ctx->first_block);
esp_sha_block(SHA1, data, first_block);
if (read_digest) {
esp_sha_read_digest_state(SHA1, ctx->state);
}
} else {
// Software mode processing can be added here if needed
esp_sha1_software_process(ctx, data);
}
#else
esp_sha1_software_process(ctx, data);
#endif
return 0;
}
int esp_internal_sha1_process( esp_sha1_context *ctx, const unsigned char data[64] )
{
return esp_internal_sha1_parallel_engine_process(ctx, data, true);
}
int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t ilen)
{
int ret = -1;
@@ -283,6 +307,12 @@ int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t il
ilen -= 64;
}
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA1, ctx->state);
}
#endif // #ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
@@ -290,22 +320,12 @@ int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t il
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 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
};
int esp_sha1_finish(esp_sha1_context *ctx, uint8_t *output)
{
@@ -331,13 +351,11 @@ int esp_sha1_finish(esp_sha1_context *ctx, uint8_t *output)
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
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA1, ctx->state);
}
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA1, ctx->state);
}
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
PUT_UINT32_BE( ctx->state[0], output, 0 );
PUT_UINT32_BE( ctx->state[1], output, 4 );
@@ -346,13 +364,32 @@ int esp_sha1_finish(esp_sha1_context *ctx, uint8_t *output)
PUT_UINT32_BE( ctx->state[4], output, 16 );
out:
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_unlock_engine(SHA1);
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
}
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
return ret;
}
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,
@@ -408,26 +445,13 @@ psa_status_t esp_sha1_driver_abort(esp_sha1_context *ctx)
if (!ctx) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1
// Also unlock the hardware engine if it was in use
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_unlock_engine(SHA1);
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
}
#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1
memset(ctx, 0, sizeof(esp_sha1_context));
return PSA_SUCCESS;
}
psa_status_t esp_sha1_driver_clone(const esp_sha1_context *source_ctx, esp_sha1_context *target_ctx)
{
if (source_ctx == NULL || target_ctx == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(target_ctx, source_ctx, sizeof(esp_sha1_context));
// If the source context is in hardware mode, we need to read the digest state
// from the hardware engine to ensure the target context has the correct state
if (source_ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA1, target_ctx->state);
target_ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; // Cloned context operates in software mode
}
return PSA_SUCCESS;
}
@@ -1,5 +1,5 @@
/*
* SHA-1 implementation with hardware ESP support added.
* SHA-256 implementation with hardware ESP support added.
*
* SPDX-FileCopyrightText: The Mbed TLS Contributors
*
@@ -37,34 +37,54 @@ do { \
} while( 0 )
#endif
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
};
psa_status_t esp_sha256_driver_clone(const esp_sha256_context *source_ctx, esp_sha256_context *target_ctx)
{
if (source_ctx == NULL || target_ctx == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(target_ctx, source_ctx, sizeof(esp_sha256_context));
// If the source context is in hardware mode, we need to read the digest state
// from the hardware engine to ensure the target context has the correct state
if (source_ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA2_256, target_ctx->state);
target_ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; // Cloned context operates in software mode
}
return PSA_SUCCESS;
}
psa_status_t esp_sha256_starts(esp_sha256_context *ctx, int is224)
psa_status_t esp_sha256_starts(esp_sha256_context *ctx, int mode)
{
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;
if ( mode == SHA2_256 ) {
/* SHA-256 */
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;
} else {
/* SHA-224 */
ctx->state[0] = 0xC1059ED8;
ctx->state[1] = 0x367CD507;
ctx->state[2] = 0x3070DD17;
ctx->state[3] = 0xF70E5939;
ctx->state[4] = 0xFFC00B31;
ctx->state[5] = 0x68581511;
ctx->state[6] = 0x64F98FA7;
ctx->state[7] = 0xBEFA4FA4;
}
// if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
// esp_sha_unlock_engine(SHA2_256);
// }
ctx->sha_state = ESP_SHA256_STATE_INIT;
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
ctx->first_block = false;
ctx->mode = mode;
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_unlock_engine(SHA2_256);
}
ctx->operation_mode = ESP_SHA_MODE_UNUSED;
return PSA_SUCCESS;
}
@@ -169,30 +189,39 @@ static void esp_sha256_software_process(esp_sha256_context *ctx, const unsigned
}
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)) {
ctx->first_block = true;
bool first_block = false;
if (ctx->operation_mode == ESP_SHA_MODE_UNUSED) {
/* try to use hardware for this digest */
if (esp_sha_try_lock_engine(SHA2_256)
#if SOC_SHA_SUPPORT_SHA224
&& (ctx->mode != SHA2_224)
#endif
) {
ctx->operation_mode = ESP_SHA_MODE_HARDWARE;
first_block = true;
} else {
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
}
ctx->sha_state = ESP_SHA256_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA256_STATE_IN_PROCESS) {
ctx->first_block = false;
}
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_block(SHA2_256, data, ctx->first_block);
esp_sha_block(SHA2_256, data, first_block);
if (read_digest) {
esp_sha_read_digest_state(SHA2_256, ctx->state);
}
} else {
// Software mode processing can be added here if needed
esp_sha256_software_process(ctx, data);
}
return 0;
}
int esp_internal_sha256_process( esp_sha256_context *ctx, const unsigned char data[64] )
{
return esp_internal_sha256_parallel_engine_process(ctx, data, true);
}
static int esp_sha256_update(esp_sha256_context *ctx, const unsigned char *input,
size_t ilen)
{
@@ -235,6 +264,10 @@ static int esp_sha256_update(esp_sha256_context *ctx, const unsigned char *input
ilen -= 64;
}
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA2_256, ctx->state);
}
if ( ilen > 0 ) {
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
@@ -242,21 +275,12 @@ static int esp_sha256_update(esp_sha256_context *ctx, const unsigned char *input
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 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_finish(esp_sha256_context *ctx, unsigned char *output)
{
@@ -283,13 +307,8 @@ static int esp_sha256_finish(esp_sha256_context *ctx, unsigned char *output)
goto out;
}
if (ctx->sha_state == ESP_SHA256_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
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA2_256, ctx->state);
} else {
}
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA2_256, ctx->state);
}
PUT_UINT32_BE( ctx->state[0], output, 0 );
@@ -307,10 +326,25 @@ out:
esp_sha_unlock_engine(SHA2_256);
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
}
memset(ctx, 0, sizeof(esp_sha256_context));
return ret;
}
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_compute(
esp_sha256_context *ctx,
psa_algorithm_t alg,
@@ -398,18 +432,3 @@ psa_status_t esp_sha256_driver_abort(esp_sha256_context *ctx)
memset(ctx, 0, sizeof(esp_sha256_context));
return PSA_SUCCESS;
}
psa_status_t esp_sha256_driver_clone(const esp_sha256_context *source_ctx, esp_sha256_context *target_ctx)
{
if (source_ctx == NULL || target_ctx == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(target_ctx, source_ctx, sizeof(esp_sha256_context));
// If the source context is in hardware mode, we need to read the digest state
// from the hardware engine to ensure the target context has the correct state
if (source_ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(SHA2_256, target_ctx->state);
target_ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; // Cloned context operates in software mode
}
return PSA_SUCCESS;
}
@@ -1,5 +1,5 @@
/*
* SHA-1 implementation with hardware ESP support added.
* SHA-512 implementation with hardware ESP support added.
*
* SPDX-FileCopyrightText: The Mbed TLS Contributors
*
@@ -51,17 +51,6 @@
}
#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
};
inline static esp_sha_type sha_type(const esp_sha512_context *ctx)
{
return ctx->mode;
@@ -96,12 +85,11 @@ psa_status_t esp_sha512_starts(esp_sha512_context *ctx, int mode)
}
ctx->mode = mode;
ctx->sha_state = ESP_SHA512_STATE_INIT;
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
ctx->first_block = false;
// if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
// esp_sha_unlock_engine(sha_type(ctx));
// }
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_unlock_engine(sha_type(ctx));
}
ctx->operation_mode = ESP_SHA_MODE_UNUSED;
return PSA_SUCCESS;
}
@@ -220,31 +208,34 @@ static void esp_sha512_software_process(esp_sha512_context *ctx, const unsigned
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) {
bool first_block = false;
if (ctx->mode == ESP_SHA_MODE_UNUSED) {
/* try to use hardware for this digest */
if (esp_sha_try_lock_engine(sha_type(ctx))) {
ctx->first_block = true;
ctx->operation_mode = ESP_SHA_MODE_HARDWARE;
ctx->mode = ESP_SHA_MODE_HARDWARE;
first_block = true;
} else {
// printf("Failed to lock SHA512 engine\n");
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
ctx->mode = ESP_SHA_MODE_SOFTWARE;
}
ctx->sha_state = ESP_SHA512_STATE_IN_PROCESS;
} else if (ctx->sha_state == ESP_SHA512_STATE_IN_PROCESS) {
ctx->first_block = false;
}
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_block(sha_type(ctx), data, ctx->first_block);
if (ctx->mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_block(sha_type(ctx), data, first_block);
if (read_digest) {
esp_sha_read_digest_state(sha_type(ctx), ctx->state);
}
} else {
// Software mode processing can be added here if needed
esp_sha512_software_process(ctx, data);
}
return 0;
}
int esp_internal_sha512_process( esp_sha512_context *ctx, const unsigned char data[128] )
{
return esp_internal_sha512_parallel_engine_process(ctx, data, true);
}
static int esp_sha512_update(esp_sha512_context *ctx, const unsigned char *input,
size_t ilen)
{
@@ -296,6 +287,17 @@ static int esp_sha512_update(esp_sha512_context *ctx, const unsigned char *input
return 0;
}
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_finish(esp_sha512_context *ctx, unsigned char *output)
{
int ret = -1;
@@ -321,12 +323,8 @@ static int esp_sha512_finish(esp_sha512_context *ctx, unsigned char *output)
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
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(sha_type(ctx), ctx->state);
}
if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) {
esp_sha_read_digest_state(sha_type(ctx), ctx->state);
}
PUT_UINT64_BE( ctx->state[0], output, 0 );
@@ -346,7 +344,6 @@ out:
esp_sha_unlock_engine(sha_type(ctx));
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
}
memset(ctx, 0, sizeof(esp_sha512_context));
return ret;
}
@@ -9,23 +9,15 @@
extern "C" {
#endif
#if defined(ESP_SHA_DRIVER_ENABLED)
#include "psa_crypto_driver_esp_sha_contexts.h"
#include <stdbool.h>
#include "psa/crypto.h"
#ifdef CONFIG_MBEDTLS_HARDWARE_SHA
#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
#endif // CONFIG_MBEDTLS_HARDWARE_SHA
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
@@ -65,13 +57,12 @@ psa_status_t esp_sha_hash_clone(
const esp_sha_hash_operation_t *source_operation,
esp_sha_hash_operation_t *target_operation);
void esp_sha1_software_process( esp_sha1_context *ctx, const unsigned char data[64] );
int esp_internal_sha1_process( esp_sha1_context *ctx, const unsigned char data[64] );
int esp_internal_sha256_process( esp_sha256_context *ctx, const unsigned char data[64] );
int esp_internal_sha512_process( esp_sha512_context *ctx, const unsigned char data[128] );
int esp_sha1_starts(esp_sha1_context *ctx);
int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t ilen);
int esp_sha1_finish(esp_sha1_context *ctx, uint8_t *output);
#endif
#ifdef __cplusplus
}
#endif
@@ -27,8 +27,6 @@ extern "C" {
#include <stdbool.h>
#include "sdkconfig.h"
#if defined(ESP_SHA_DRIVER_ENABLED)
typedef enum {
ESP_SHA_OPERATION_TYPE_SHA1,
ESP_SHA_OPERATION_TYPE_SHA256,
@@ -57,8 +55,9 @@ typedef enum {
#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG
typedef enum {
ESP_SHA_MODE_SOFTWARE,
ESP_SHA_MODE_HARDWARE
ESP_SHA_MODE_UNUSED,
ESP_SHA_MODE_HARDWARE,
ESP_SHA_MODE_SOFTWARE
} esp_sha_mode_t;
#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */
@@ -120,8 +119,6 @@ typedef struct {
esp_sha_operation_type_t sha_type;
} esp_sha_hash_operation_t;
#endif /* ESP_SHA_DRIVER_ENABLED */
#ifdef __cplusplus
}
#endif
@@ -10,7 +10,6 @@ set(TEST_CRTS "crts/server_cert_chain.pem"
idf_component_register(
SRC_DIRS "."
# 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}
@@ -345,12 +345,6 @@ static int hmac_vector(psa_algorithm_t alg,
goto err;
}
status = psa_mac_abort(&operation);
if (status != PSA_SUCCESS) {
ret = -1;
goto err;
}
status = psa_destroy_key(key_id);
if (status != PSA_SUCCESS) {
ret = -1;
@@ -364,6 +358,7 @@ err:
if (key_id) {
psa_destroy_key(key_id);
}
psa_mac_abort(&operation);
}
return ret;
@@ -783,9 +778,11 @@ cleanup:
psa_destroy_key(key_id);
}
if (enc_operation) {
psa_cipher_abort(enc_operation);
os_free(enc_operation);
}
if (dec_operation) {
psa_cipher_abort(dec_operation);
os_free(dec_operation);
}
psa_reset_key_attributes(&attributes);
@@ -29,7 +29,6 @@
#include "mbedtls/esp_config.h"
#include "utils/wpa_debug.h"
#include "psa/crypto.h"
#define ESP_SHA_DRIVER_ENABLED
#include "psa_crypto_driver_esp_sha.h"
/* --- MSVC doesn't support C99 --- */
@@ -300,9 +299,7 @@ static int esp_sha1_init_start(esp_sha1_context *ctx)
esp_sha1_starts(ctx);
#if defined(CONFIG_IDF_TARGET_ESP32) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
/* Use software mode for esp32 since hardware can't give output more than 20 */
// esp_mbedtls_set_sha1_mode(ctx, ESP_MBEDTLS_SHA1_SOFTWARE);
ctx->operation_mode = ESP_SHA_MODE_SOFTWARE;
ctx->sha_state = ESP_SHA1_STATE_IN_PROCESS;
#endif
return 0;
}
@@ -329,7 +326,9 @@ static int sha1_finish(esp_sha1_context *ctx,
/* We'll need an extra block */
memset(ctx->MBEDTLS_PRIVATE(buffer) + used, 0, 64 - used);
esp_sha1_software_process(ctx, ctx->MBEDTLS_PRIVATE(buffer));
if ((ret = esp_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) {
goto exit;
}
memset(ctx->MBEDTLS_PRIVATE(buffer), 0, 56);
}
@@ -344,7 +343,9 @@ static int sha1_finish(esp_sha1_context *ctx,
write32_be(high, ctx->MBEDTLS_PRIVATE(buffer) + 56);
write32_be(low, ctx->MBEDTLS_PRIVATE(buffer) + 60);
esp_sha1_software_process(ctx, ctx->MBEDTLS_PRIVATE(buffer));
if ((ret = esp_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) {
goto exit;
}
/*
* Output final state
@@ -357,6 +358,7 @@ static int sha1_finish(esp_sha1_context *ctx,
ret = 0;
exit:
return ret;
}
#endif
@@ -367,7 +369,7 @@ DECL_PBKDF2(sha1, // _name
esp_sha1_context, // _ctx
esp_sha1_init_start, // _init
esp_sha1_update, // _update
esp_sha1_software_process, // _xform
esp_internal_sha1_process, // _xform
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
esp_sha1_finish, // _final
#else
@@ -63,7 +63,6 @@
#include "sha/sha_core.h"
#endif
#include "esp_log.h"
#include "psa/crypto.h"
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n, b, i) \
@@ -257,6 +256,10 @@ void fast_psk_f(const char *password, size_t password_len, const uint8_t *ssid,
int esp_fast_psk(const char *password, size_t password_len, const uint8_t *ssid, size_t ssid_len, size_t iterations, uint8_t *output, size_t output_len)
{
if (!(ssid_len <= 32 && password_len <= 63 && iterations == 4096 && output_len == 32)) {
return -1; /* Invalid input parameters */
}
/* Compute the first 16 bytes of the PSK */
fast_psk_f(password, password_len, ssid, ssid_len, 2, output);
@@ -12,7 +12,7 @@
#include "test_wpa_supplicant_common.h"
#define PMK_LEN 32
#define NUM_ITERATIONS 3
#define NUM_ITERATIONS 5
#define MIN_PASSPHARSE_LEN 8
void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw,