diff --git a/components/bootloader_support/private_include/bootloader_sha.h b/components/bootloader_support/private_include/bootloader_sha.h index b4eec76484c..661aa8028ee 100644 --- a/components/bootloader_support/private_include/bootloader_sha.h +++ b/components/bootloader_support/private_include/bootloader_sha.h @@ -9,7 +9,7 @@ that can be used from bootloader or app code. This header is available to source code in the bootloader & bootloader_support components only. - Use mbedTLS APIs or include esp32/sha.h to calculate SHA256 in IDF apps. + Use PSA APIs or include esp32/sha.h to calculate SHA256 in IDF apps. */ #include diff --git a/components/bootloader_support/src/bootloader_sha.c b/components/bootloader_support/src/bootloader_sha.c index e4b553a5b7d..d771e1caf85 100644 --- a/components/bootloader_support/src/bootloader_sha.c +++ b/components/bootloader_support/src/bootloader_sha.c @@ -179,81 +179,117 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest #else /* NON_OS_BUILD || CONFIG_APP_BUILD_TYPE_RAM */ #include "bootloader_flash_priv.h" -#include -#include +#include "psa/crypto.h" bootloader_sha256_handle_t bootloader_sha256_start(void) { - mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context)); - if (!ctx) { + psa_hash_operation_t *op = (psa_hash_operation_t *)malloc(sizeof(psa_hash_operation_t)); + if (!op) { return NULL; } - mbedtls_sha256_init(ctx); - int ret = mbedtls_sha256_starts(ctx, false); - if (ret != 0) { + + *op = psa_hash_operation_init(); + psa_status_t status = psa_hash_setup(op, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { + free(op); return NULL; } - return ctx; + + return (bootloader_sha256_handle_t)op; } void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len) { assert(handle != NULL); - mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle; - int ret = mbedtls_sha256_update(ctx, data, data_len); - assert(ret == 0); - (void)ret; + psa_hash_operation_t *op = (psa_hash_operation_t *)handle; + + psa_status_t status = psa_hash_update(op, data, data_len); + assert(status == PSA_SUCCESS); + (void)status; // Suppress unused variable warning in release builds } void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest) { assert(handle != NULL); - mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle; + psa_hash_operation_t *op = (psa_hash_operation_t *)handle; + if (digest != NULL) { - int ret = mbedtls_sha256_finish(ctx, digest); - assert(ret == 0); - (void)ret; + size_t hash_len; + psa_status_t status = psa_hash_finish(op, digest, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_len); + assert(status == PSA_SUCCESS); + assert(hash_len == PSA_HASH_LENGTH(PSA_ALG_SHA_256)); + (void)status; // Suppress unused variable warning in release builds + (void)hash_len; // Suppress unused variable warning in release builds + } else { + psa_hash_abort(op); } - mbedtls_sha256_free(ctx); + free(handle); handle = NULL; } #if SOC_SHA_SUPPORT_SHA512 + +typedef struct { + psa_hash_operation_t *hash_op; + int psa_alg; +} bootloader_psa_sha_handle_t; + bootloader_sha_handle_t bootloader_sha512_start(bool is384) { - mbedtls_sha512_context *ctx = (mbedtls_sha512_context *)malloc(sizeof(mbedtls_sha512_context)); - if (!ctx) { + psa_status_t status; + bootloader_psa_sha_handle_t *op = (bootloader_psa_sha_handle_t *)malloc(sizeof(bootloader_psa_sha_handle_t)); + if (!op) { return NULL; } - mbedtls_sha512_init(ctx); - int ret = mbedtls_sha512_starts(ctx, is384); - if (ret != 0) { + + op->hash_op = (psa_hash_operation_t *)malloc(sizeof(psa_hash_operation_t)); + if (!op->hash_op) { + free(op); return NULL; } - return ctx; + + op->psa_alg = is384 ? PSA_ALG_SHA_384 : PSA_ALG_SHA_512; + + *op->hash_op = psa_hash_operation_init(); + status = psa_hash_setup(op->hash_op, op->psa_alg); + if (status != PSA_SUCCESS) { + free(op->hash_op); + free(op); + return NULL; + } + + return (bootloader_psa_sha_handle_t *)op; } void bootloader_sha512_data(bootloader_sha_handle_t handle, const void *data, size_t data_len) { assert(handle != NULL); - mbedtls_sha512_context *ctx = (mbedtls_sha512_context *)handle; - int ret = mbedtls_sha512_update(ctx, data, data_len); - assert(ret == 0); - (void)ret; + bootloader_psa_sha_handle_t *op = (bootloader_psa_sha_handle_t *)handle; + + psa_status_t status = psa_hash_update(op->hash_op, data, data_len); + assert(status == PSA_SUCCESS); + (void)status; // Suppress unused variable warning in release builds } void bootloader_sha512_finish(bootloader_sha_handle_t handle, uint8_t *digest) { assert(handle != NULL); - mbedtls_sha512_context *ctx = (mbedtls_sha512_context *)handle; + bootloader_psa_sha_handle_t *op = (bootloader_psa_sha_handle_t *)handle; + if (digest != NULL) { - int ret = mbedtls_sha512_finish(ctx, digest); - assert(ret == 0); - (void)ret; + size_t hash_len; + psa_status_t status = psa_hash_finish(op->hash_op, digest, PSA_HASH_LENGTH(op->psa_alg), &hash_len); + assert(status == PSA_SUCCESS); + assert(hash_len == PSA_HASH_LENGTH(op->psa_alg)); + (void)status; // Suppress unused variable warning in release builds + (void)hash_len; // Suppress unused variable warning in release builds + } else { + psa_hash_abort(op->hash_op); } - mbedtls_sha512_free(ctx); - free(handle); + + free(op->hash_op); + free(op); handle = NULL; } #endif /* SOC_SHA_SUPPORT_SHA512 */ diff --git a/components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_app.c b/components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_app.c index c7057014cf3..92be1b5a52a 100644 --- a/components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_app.c +++ b/components/bootloader_support/src/secure_boot_v1/secure_boot_signatures_app.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,14 +11,11 @@ #include "esp_log.h" #include "esp_image_format.h" #include "esp_secure_boot.h" -#include "mbedtls/sha256.h" -#include "mbedtls/x509.h" -#include "mbedtls/md.h" -#include "mbedtls/platform.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" +#include "psa/crypto.h" #include #include +#include "mbedtls/pk.h" + #ifdef CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME ESP_LOG_ATTR_TAG(TAG, "secure_boot_v1"); @@ -27,7 +24,9 @@ extern const uint8_t signature_verification_key_start[] asm("_binary_signature_v extern const uint8_t signature_verification_key_end[] asm("_binary_signature_verification_key_bin_end"); #define SIGNATURE_VERIFICATION_KEYLEN 64 - +#define PSA_ECDSA_PUB_KEY_SIZE_BITS 256 +#define UNCOMPRESSED_SECP256R1_KEY_SIZE 65 // Size for uncompressed SECP256R1 (1 + 32 + 32) +#define ECC_UNCOMPRESSED_POINT_FORMAT_INDICATOR 0x04 esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length) { uint8_t digest[ESP_SECURE_BOOT_DIGEST_LEN]; @@ -76,53 +75,47 @@ esp_err_t esp_secure_boot_verify_ecdsa_signature_block(const esp_secure_boot_sig } ESP_LOGD(TAG, "Verifying secure boot signature"); + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_handle; - int ret; - mbedtls_mpi r, s; + // Format the public key for PSA import + uint8_t formatted_key[UNCOMPRESSED_SECP256R1_KEY_SIZE]; + formatted_key[0] = ECC_UNCOMPRESSED_POINT_FORMAT_INDICATOR; - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - - /* Extract r and s components from RAW ECDSA signature of 64 bytes */ -#define ECDSA_INTEGER_LEN 32 - ret = mbedtls_mpi_read_binary(&r, &sig_block->signature[0], ECDSA_INTEGER_LEN); - if (ret != 0) { - ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(1), err:%d", ret); + // Copy X and Y coordinates + if (keylen == 64) { // Raw coordinates without format byte + memcpy(&formatted_key[1], signature_verification_key_start, 64); + } else if (keylen == UNCOMPRESSED_SECP256R1_KEY_SIZE && signature_verification_key_start[0] == ECC_UNCOMPRESSED_POINT_FORMAT_INDICATOR) { + // Key is already in correct format + memcpy(formatted_key, signature_verification_key_start, UNCOMPRESSED_SECP256R1_KEY_SIZE); + } else { + ESP_LOGE(TAG, "Invalid key format or length"); return ESP_FAIL; } - ret = mbedtls_mpi_read_binary(&s, &sig_block->signature[ECDSA_INTEGER_LEN], ECDSA_INTEGER_LEN); - if (ret != 0) { - ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(2), err:%d", ret); - mbedtls_mpi_free(&r); + // Set key attributes + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, PSA_ECDSA_PUB_KEY_SIZE_BITS); + + // Import the properly formatted public key + status = psa_import_key(&key_attributes, formatted_key, sizeof(formatted_key), &key_handle); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to import key, status:%d", status); return ESP_FAIL; } - /* Initialise ECDSA context */ - mbedtls_ecdsa_context ecdsa_context; - mbedtls_ecdsa_init(&ecdsa_context); + // Verify the signature + status = psa_verify_hash(key_handle, PSA_ALG_ECDSA(PSA_ALG_SHA_256), image_digest, ESP_SECURE_BOOT_DIGEST_LEN, sig_block->signature, SIGNATURE_VERIFICATION_KEYLEN); + ESP_LOGI(TAG, "Verification result %d", status); - mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); - size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P); - if (keylen != 2 * plen) { - ESP_LOGE(TAG, "Incorrect ECDSA key length %d", keylen); - ret = ESP_FAIL; - goto cleanup; - } + // Destroy the key handle + psa_destroy_key(key_handle); + psa_reset_key_attributes(&key_attributes); - /* Extract X and Y components from ECDSA public key */ - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), signature_verification_key_start, plen)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), signature_verification_key_start + plen, plen)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1)); - - ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), image_digest, ESP_SECURE_BOOT_DIGEST_LEN, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s); - ESP_LOGD(TAG, "Verification result %d", ret); - -cleanup: - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - mbedtls_ecdsa_free(&ecdsa_context); - return ret == 0 ? ESP_OK : ESP_ERR_IMAGE_INVALID; + return status == PSA_SUCCESS ? ESP_OK : ESP_ERR_IMAGE_INVALID; #endif // CONFIG_MBEDTLS_ECDSA_C && CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED } #endif // CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_ecdsa_signature.c b/components/bootloader_support/src/secure_boot_v2/secure_boot_ecdsa_signature.c index 2eeff0da558..6f716b24e16 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_ecdsa_signature.c +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_ecdsa_signature.c @@ -5,15 +5,9 @@ */ #include "esp_log.h" #include "esp_secure_boot.h" -#include "mbedtls/sha256.h" -#include "mbedtls/x509.h" -#include "mbedtls/md.h" -#include "mbedtls/platform.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/ecp.h" #include "rom/ecdsa.h" #include "sdkconfig.h" +#include "psa/crypto.h" #include "secure_boot_signature_priv.h" @@ -31,32 +25,35 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl return ESP_ERR_INVALID_ARG; } - esp_err_t ret; + esp_err_t ret = ESP_OK; + psa_status_t status; - mbedtls_mpi r, s; + /* Prepare public key for verification */ + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_handle = 0; - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - - /* Initialise ECDSA context */ - mbedtls_ecdsa_context ecdsa_context; - mbedtls_ecdsa_init(&ecdsa_context); + /* Set key attributes according to the curve */ + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH); uint8_t key_size = 0; + psa_ecc_family_t curve_family; switch(trusted_block->ecdsa.key.curve_id) { case ECDSA_CURVE_P192: key_size = 24; - mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP192R1); + curve_family = PSA_ECC_FAMILY_SECP_R1; + psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size)); break; case ECDSA_CURVE_P256: key_size = 32; - mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); + curve_family = PSA_ECC_FAMILY_SECP_R1; + psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size)); break; #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,50 +61,58 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl return ESP_ERR_INVALID_ARG; } - uint8_t x_point[ECDSA_INTEGER_LEN] = {}; - uint8_t y_point[ECDSA_INTEGER_LEN] = {}; - uint8_t _r[ECDSA_INTEGER_LEN] = {}; - uint8_t _s[ECDSA_INTEGER_LEN] = {}; + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve_family)); - /* Convert r and s components to big endian format */ + /* Prepare the public key data from X and Y coordinates */ + 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++) { - _r[i] = trusted_block->ecdsa.signature[key_size - i - 1]; - _s[i] = trusted_block->ecdsa.signature[2 * key_size - i - 1]; + 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]; } - /* Extract r and s components from RAW ECDSA signature of 64 bytes */ - ret = mbedtls_mpi_read_binary(&r, _r, key_size); - if (ret != 0) { - ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(r), err:%d", ret); - mbedtls_ecdsa_free(&ecdsa_context); - return ESP_FAIL; + public_key[0] = 0x04; /* Uncompressed point format */ + + /* Combine X and Y into a single public key buffer */ + 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) + 1, &key_handle); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to import key, err:%d", status); + ret = ESP_FAIL; + goto cleanup; } - ret = mbedtls_mpi_read_binary(&s, _s, key_size); - if (ret != 0) { - ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(s), err:%d", ret); - mbedtls_mpi_free(&r); - mbedtls_ecdsa_free(&ecdsa_context); - return ESP_FAIL; + /* Convert signature from little-endian to big-endian format */ + uint8_t signature[2 * ECDSA_INTEGER_LEN] = {0}; + for (int i = 0; i < key_size; i++) { + signature[i] = trusted_block->ecdsa.signature[key_size - i - 1]; + signature[key_size + i] = trusted_block->ecdsa.signature[2 * key_size - i - 1]; } - size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P); + /* Verify the signature */ + status = psa_verify_hash(key_handle, PSA_ALG_ECDSA(PSA_ALG_SHA_256), + image_digest, ESP_SECURE_BOOT_DIGEST_LEN, + signature, 2 * key_size); - for (int i = 0; i < plen; i++) { - x_point[i] = trusted_block->ecdsa.key.point[plen - 1 - i]; - y_point[i] = trusted_block->ecdsa.key.point[2 * plen - 1 - i]; + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Signature verification failed, err:%d", status); + ret = ESP_FAIL; } - /* Extract X and Y components from ECDSA public key */ - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), x_point, plen)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), y_point, plen)); - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1)); - - ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), image_digest, ESP_SECURE_BOOT_DIGEST_LEN, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s); - cleanup: - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - mbedtls_ecdsa_free(&ecdsa_context); + /* Clean up resources */ + if (key_handle) { + psa_destroy_key(key_handle); + } + psa_reset_key_attributes(&key_attributes); + return ret; } diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_rsa_signature.c b/components/bootloader_support/src/secure_boot_v2/secure_boot_rsa_signature.c index ce63ba9bcc7..7f815214f67 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_rsa_signature.c +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_rsa_signature.c @@ -1,76 +1,166 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "esp_log.h" #include "esp_secure_boot.h" -#include "mbedtls/sha256.h" +#include "psa/crypto.h" +#include "mbedtls/asn1.h" +#include "mbedtls/asn1write.h" #include "mbedtls/x509.h" -#include "mbedtls/md.h" -#include "mbedtls/platform.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #include "secure_boot_signature_priv.h" ESP_LOG_ATTR_TAG(TAG, "secure_boot_v2_rsa"); +/* + * Helper function to encode RSA public key (N, e) into DER format manually + * This creates a PKCS#1 RSAPublicKey structure: + * + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ +static int encode_rsa_pubkey_der(const uint8_t *modulus, size_t modulus_len, + const uint8_t *exponent, size_t exponent_len, + uint8_t *der_buf, size_t der_buf_size, + uint8_t **der_start, size_t *der_len) +{ + if (!der_buf || !der_start || !der_len || der_buf_size == 0) { + return MBEDTLS_ERR_X509_BAD_INPUT_DATA; + } + + int ret; + unsigned char *c = der_buf + der_buf_size; + size_t len = 0; + + /* Write the exponent (e) as an INTEGER */ + /* Skip leading zeros in exponent */ + while (exponent_len > 0 && *exponent == 0) { + exponent++; + exponent_len--; + } + + /* Write exponent */ + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, der_buf, exponent, exponent_len)); + + /* Add padding byte if MSB is set (to keep it positive) */ + if (exponent_len > 0 && (exponent[0] & 0x80)) { + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, der_buf, (const unsigned char *)"\x00", 1)); + } + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, der_buf, exponent_len + ((exponent[0] & 0x80) ? 1 : 0))); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, der_buf, MBEDTLS_ASN1_INTEGER)); + + /* Write the modulus (N) as an INTEGER */ + /* Skip leading zeros in modulus */ + const uint8_t *mod_ptr = modulus; + size_t mod_len = modulus_len; + while (mod_len > 0 && *mod_ptr == 0) { + mod_ptr++; + mod_len--; + } + + /* Write modulus */ + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, der_buf, mod_ptr, mod_len)); + + /* Add padding byte if MSB is set */ + if (mod_len > 0 && (mod_ptr[0] & 0x80)) { + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, der_buf, (const unsigned char *)"\x00", 1)); + } + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, der_buf, mod_len + ((mod_ptr[0] & 0x80) ? 1 : 0))); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, der_buf, MBEDTLS_ASN1_INTEGER)); + + /* Write SEQUENCE header */ + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, der_buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, der_buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); + + *der_start = c; + *der_len = len; + + return 0; +} + esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, const ets_secure_boot_sig_block_t *trusted_block) { if (!sig_block || !image_digest || !trusted_block) { return ESP_ERR_INVALID_ARG; } - int ret = 0; - mbedtls_rsa_context pk; - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; + esp_err_t ret = ESP_OK; + psa_status_t status; const unsigned rsa_key_size = sizeof(sig_block->block[0].signature); - unsigned char *sig_be = calloc(1, rsa_key_size); + unsigned char *sig_be = NULL; + unsigned char *pubkey_der_buf = NULL; + + sig_be = calloc(1, rsa_key_size); if (sig_be == NULL) { return ESP_ERR_NO_MEM; } - unsigned char *buf = calloc(1, rsa_key_size); - if (buf == NULL) { + + /* Create key attributes for RSA public key */ + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + + /* Allocate buffer for DER-encoded public key */ + size_t pubkey_der_buf_size = PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(3072); + pubkey_der_buf = calloc(1, pubkey_der_buf_size); + if (pubkey_der_buf == NULL) { free(sig_be); return ESP_ERR_NO_MEM; } - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_init(&ctr_drbg); - ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0); - if (ret != 0) { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x", ret); - goto exit_outer; + /* Convert raw N and e to DER format manually */ + uint8_t *der_start = NULL; + size_t der_len = 0; + + /* Convert modulus from little-endian to big-endian */ + uint8_t *n_be = calloc(1, rsa_key_size); + if (n_be == NULL) { + free(sig_be); + free(pubkey_der_buf); + return ESP_ERR_NO_MEM; + } + for (size_t i = 0; i < rsa_key_size; i++) { + n_be[i] = trusted_block->key.n[rsa_key_size - 1 - i]; } - const mbedtls_mpi N = { .MBEDTLS_PRIVATE(s) = 1, - .MBEDTLS_PRIVATE(n) = sizeof(trusted_block->key.n)/sizeof(mbedtls_mpi_uint), - .MBEDTLS_PRIVATE(p) = (void *)trusted_block->key.n, - }; - const mbedtls_mpi e = { .MBEDTLS_PRIVATE(s) = 1, - .MBEDTLS_PRIVATE(n) = sizeof(trusted_block->key.e)/sizeof(mbedtls_mpi_uint), // 1 - .MBEDTLS_PRIVATE(p) = (void *)&trusted_block->key.e, - }; - mbedtls_rsa_init(&pk); - mbedtls_rsa_set_padding(&pk,MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256); - ret = mbedtls_rsa_import(&pk, &N, NULL, NULL, NULL, &e); + /* Convert e from uint32_t to byte array (big-endian) */ + uint8_t e_bytes[4]; + e_bytes[0] = (trusted_block->key.e >> 24) & 0xFF; + e_bytes[1] = (trusted_block->key.e >> 16) & 0xFF; + e_bytes[2] = (trusted_block->key.e >> 8) & 0xFF; + e_bytes[3] = trusted_block->key.e & 0xFF; + + ret = encode_rsa_pubkey_der( + n_be, rsa_key_size, + e_bytes, sizeof(e_bytes), + pubkey_der_buf, pubkey_der_buf_size, + &der_start, &der_len + ); + + free(n_be); + if (ret != 0) { - ESP_LOGE(TAG, "Failed mbedtls_rsa_import, err: %d", ret); - goto exit_inner; + ESP_LOGE(TAG, "Failed to encode RSA public key to DER, err: %d", ret); + goto cleanup; } - ret = mbedtls_rsa_complete(&pk); - if (ret != 0) { - ESP_LOGE(TAG, "Failed mbedtls_rsa_complete, err: %d", ret); - goto exit_inner; - } + /* Set key attributes */ + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attributes, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY); - ret = mbedtls_rsa_check_pubkey(&pk); - if (ret != 0) { - ESP_LOGI(TAG, "Key is not an RSA key -%0x", -ret); - goto exit_inner; + /* Import DER-encoded public key into PSA */ + status = psa_import_key(&key_attributes, der_start, der_len, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to import key into PSA, err: %d", status); + ret = ESP_FAIL; + goto cleanup; } /* Signature needs to be byte swapped into BE representation */ @@ -78,24 +168,27 @@ esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_bloc sig_be[rsa_key_size - j - 1] = trusted_block->signature[j]; } - ret = mbedtls_rsa_public( &pk, sig_be, buf); - if (ret != 0) { - ESP_LOGE(TAG, "mbedtls_rsa_public failed, err: %d", ret); - goto exit_inner; - } + /* Verify the signature using PSA APIs */ + status = psa_verify_hash(key_id, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256), + image_digest, ESP_SECURE_BOOT_DIGEST_LEN, + sig_be, rsa_key_size); - ret = mbedtls_rsa_rsassa_pss_verify( &pk, MBEDTLS_MD_SHA256, ESP_SECURE_BOOT_DIGEST_LEN, image_digest, sig_be); - if (ret != 0) { - ESP_LOGE(TAG, "Failed mbedtls_rsa_rsassa_pss_verify, err: %d", ret); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Signature verification failed, err: %d", status); + ret = ESP_FAIL; } else { ESP_LOGI(TAG, "Signature verified successfully!"); + ret = ESP_OK; } -exit_inner: - mbedtls_rsa_free(&pk); -exit_outer: - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); + +cleanup: + /* Clean up resources */ + if (key_id != 0) { + psa_destroy_key(key_id); + } + psa_reset_key_attributes(&key_attributes); free(sig_be); - free(buf); + free(pubkey_der_buf); + return ret; } diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c index bdba167567b..2c7347a15b4 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c @@ -11,12 +11,6 @@ #include "bootloader_signature.h" #include "esp_log.h" #include "esp_image_format.h" -#include "mbedtls/sha256.h" -#include "mbedtls/x509.h" -#include "mbedtls/md.h" -#include "mbedtls/platform.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #include #include #include "esp_secure_boot.h" diff --git a/components/bt/common/btc/profile/esp/blufi/include/blufi_int.h b/components/bt/common/btc/profile/esp/blufi/include/blufi_int.h index a7f4f292884..248b97adecb 100644 --- a/components/bt/common/btc/profile/esp/blufi/include/blufi_int.h +++ b/components/bt/common/btc/profile/esp/blufi/include/blufi_int.h @@ -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; diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 506dc13cd19..1daade25f86 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -1443,19 +1443,12 @@ uint8_t esp_ble_get_chip_rev_version(void) #if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 +#define BLE_PUB_KEY_LEN 65 #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#include "mbedtls/aes.h" #if CONFIG_BT_LE_SM_SC -#include "mbedtls/cipher.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/cmac.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/ecp.h" - -static mbedtls_ecp_keypair keypair; +#include "psa/crypto.h" +static const char *TAG_SM_ALG = "ble_sm_alg"; #endif // CONFIG_BT_LE_SM_SC - #else #include "tinycrypt/aes.h" #include "tinycrypt/constants.h" @@ -1499,84 +1492,56 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ const uint8_t *our_priv_key, uint8_t *out_dhkey) { uint8_t dh[32]; - uint8_t pk[64]; + uint8_t pk[BLE_PUB_KEY_LEN]; uint8_t priv[32]; int rc = BLE_SM_KEY_ERR; - swap_buf(pk, peer_pub_key_x, 32); - swap_buf(&pk[32], peer_pub_key_y, 32); swap_buf(priv, our_priv_key, 32); #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS - struct mbedtls_ecp_point pt = {0}, Q = {0}; - mbedtls_mpi z = {0}, d = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; - mbedtls_entropy_context entropy = {0}; + // PSA expects 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + pk[0] = 0x04; // Uncompressed format for public key + swap_buf(&pk[1], peer_pub_key_x, 32); + swap_buf(&pk[33], peer_pub_key_y, 32); - uint8_t pub[65] = {0}; - /* Hardcoded first byte of pub key for MBEDTLS_ECP_PF_UNCOMPRESSED */ - pub[0] = 0x04; - memcpy(&pub[1], pk, 64); + psa_key_id_t key_id = 0; + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - /* Initialize the required structures here */ - mbedtls_ecp_point_init(&pt); - mbedtls_ecp_point_init(&Q); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_entropy_init(&entropy); - mbedtls_mpi_init(&d); - mbedtls_mpi_init(&z); - - /* Below 3 steps are to validate public key on curve secp256r1 */ - if (mbedtls_ecp_group_load(&keypair.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1) != 0) { + status = psa_import_key(&key_attributes, priv, 32, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG_SM_ALG, "Failed to import key: %d", status); + goto exit; + } + psa_reset_key_attributes(&key_attributes); + size_t output_len = 0; + status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, pk, BLE_PUB_KEY_LEN, dh, sizeof(dh), &output_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG_SM_ALG, "Failed to perform raw key agreement: %d", status); goto exit; } - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &pt, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_ecp_check_pubkey(&keypair.MBEDTLS_PRIVATE(grp), &pt) != 0) { - goto exit; - } - - /* Set PRNG */ - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { - goto exit; - } - - /* Prepare point Q from pub key */ - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &Q, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_mpi_read_binary(&d, priv, 32) != 0) { - goto exit; - } - - rc = mbedtls_ecdh_compute_shared(&keypair.MBEDTLS_PRIVATE(grp), &z, &Q, &d, - mbedtls_ctr_drbg_random, &ctr_drbg); - if (rc != 0) { - goto exit; - } - - rc = mbedtls_mpi_write_binary(&z, dh, 32); - if (rc != 0) { + if (output_len != 32) { + ESP_LOGE(TAG_SM_ALG, "Unexpected output length: %zu", output_len); goto exit; } + rc = 0; exit: - mbedtls_ecp_point_free(&pt); - mbedtls_mpi_free(&z); - mbedtls_mpi_free(&d); - mbedtls_ecp_point_free(&Q); - mbedtls_entropy_free(&entropy); - mbedtls_ctr_drbg_free(&ctr_drbg); if (rc != 0) { return BLE_SM_KEY_ERR; } #else - if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { + // tinycrypt expects 64 bytes: X (32 bytes) + Y (32 bytes), no prefix + swap_buf(pk, peer_pub_key_x, 32); + swap_buf(&pk[32], peer_pub_key_y, 32); + + if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { return BLE_SM_KEY_ERR; } @@ -1594,42 +1559,38 @@ exit: static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) { int rc = BLE_SM_KEY_ERR; - mbedtls_entropy_context entropy = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_algorithm_t alg = PSA_ALG_ECDH; + psa_key_type_t key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); + psa_key_usage_t key_usage = PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT; - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_ecp_keypair_init(&keypair); - - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { - goto exit; - } - - if ((rc = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, &keypair, - mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) { - goto exit; - } - - if ((rc = mbedtls_mpi_write_binary(&keypair.MBEDTLS_PRIVATE(d), private_key, 32)) != 0) { + psa_set_key_type(&key_attributes, key_type); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, alg); + psa_set_key_usage_flags(&key_attributes, key_usage); + status = psa_generate_key(&key_attributes, &key_id); + if (status != PSA_SUCCESS) { goto exit; } + psa_reset_key_attributes(&key_attributes); size_t olen = 0; - uint8_t pub[65] = {0}; - - if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, pub, 65)) != 0) { + 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; } - memcpy(public_key, &pub[1], 64); + status = psa_export_key(key_id, private_key, 32, &olen); + if (status != PSA_SUCCESS || olen != 32) { + goto exit; + } + psa_destroy_key(key_id); + rc = 0; exit: - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); if (rc != 0) { - mbedtls_ecp_keypair_free(&keypair); return BLE_SM_KEY_ERR; } @@ -1638,7 +1599,7 @@ exit: #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS /** - * pub: 64 bytes + * pub: BLE_PUB_KEY_LEN bytes * priv: 32 bytes */ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) @@ -1648,7 +1609,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) swap_buf(&pub[32], &ble_sm_alg_dbg_pub_key[32], 32); swap_buf(priv, ble_sm_alg_dbg_priv_key, 32); #else - uint8_t pk[64]; + uint8_t pk[BLE_PUB_KEY_LEN]; do { #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1663,8 +1624,16 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) /* Make sure generated key isn't debug key. */ } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); +#if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS + // PSA returns 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + // Skip the 0x04 prefix when copying to pub + swap_buf(pub, &pk[1], 32); + swap_buf(&pub[32], &pk[33], 32); +#else + // tinycrypt returns 64 bytes: X (32 bytes) + Y (32 bytes), no prefix swap_buf(pub, pk, 32); swap_buf(&pub[32], &pk[32], 32); +#endif swap_in_place(priv, 32); #endif // CONFIG_BT_LE_SM_SC_DEBUG_KEYS return 0; diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index 6354eb99284..56334374a0f 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -1585,19 +1585,12 @@ void esp_ble_controller_log_dump_all(bool output) #if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 +#define BLE_PUB_KEY_LEN 65 #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#include "mbedtls/aes.h" #if CONFIG_BT_LE_SM_SC -#include "mbedtls/cipher.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/cmac.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/ecp.h" - -static mbedtls_ecp_keypair keypair; +#include "psa/crypto.h" +static const char *TAG_SM_ALG = "ble_sm_alg"; #endif // CONFIG_BT_LE_SM_SC - #else #include "tinycrypt/aes.h" #include "tinycrypt/constants.h" @@ -1640,84 +1633,58 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ const uint8_t *our_priv_key, uint8_t *out_dhkey) { uint8_t dh[32]; - uint8_t pk[64]; + uint8_t pk[BLE_PUB_KEY_LEN]; uint8_t priv[32]; int rc = BLE_SM_KEY_ERR; - swap_buf(pk, peer_pub_key_x, 32); - swap_buf(&pk[32], peer_pub_key_y, 32); swap_buf(priv, our_priv_key, 32); #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS - struct mbedtls_ecp_point pt = {0}, Q = {0}; - mbedtls_mpi z = {0}, d = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; - mbedtls_entropy_context entropy = {0}; + // PSA/mbedTLS expects 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + pk[0] = 0x04; // Uncompressed format for public key + swap_buf(&pk[1], peer_pub_key_x, 32); + swap_buf(&pk[33], peer_pub_key_y, 32); - uint8_t pub[65] = {0}; - /* Hardcoded first byte of pub key for MBEDTLS_ECP_PF_UNCOMPRESSED */ - pub[0] = 0x04; - memcpy(&pub[1], pk, 64); - - /* Initialize the required structures here */ - mbedtls_ecp_point_init(&pt); - mbedtls_ecp_point_init(&Q); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_entropy_init(&entropy); - mbedtls_mpi_init(&d); - mbedtls_mpi_init(&z); - - /* Below 3 steps are to validate public key on curve secp256r1 */ - if (mbedtls_ecp_group_load(&keypair.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1) != 0) { + psa_key_id_t key_id = 0; + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); + status = psa_import_key(&key_attributes, priv, 32, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG_SM_ALG, "Failed to import key: %d", status); + goto exit; + } + psa_reset_key_attributes(&key_attributes); + size_t output_len = 0; + status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, pk, BLE_PUB_KEY_LEN, dh, sizeof(dh), &output_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG_SM_ALG, "Failed to perform raw key agreement: %d", status); goto exit; } - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &pt, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_ecp_check_pubkey(&keypair.MBEDTLS_PRIVATE(grp), &pt) != 0) { - goto exit; - } - - /* Set PRNG */ - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { - goto exit; - } - - /* Prepare point Q from pub key */ - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &Q, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_mpi_read_binary(&d, priv, 32) != 0) { - goto exit; - } - - rc = mbedtls_ecdh_compute_shared(&keypair.MBEDTLS_PRIVATE(grp), &z, &Q, &d, - mbedtls_ctr_drbg_random, &ctr_drbg); - if (rc != 0) { - goto exit; - } - - rc = mbedtls_mpi_write_binary(&z, dh, 32); - if (rc != 0) { + if (output_len != 32) { + ESP_LOGE(TAG_SM_ALG, "Unexpected output length: %zu", output_len); goto exit; } + rc = 0; exit: - mbedtls_ecp_point_free(&pt); - mbedtls_mpi_free(&z); - mbedtls_mpi_free(&d); - mbedtls_ecp_point_free(&Q); - mbedtls_entropy_free(&entropy); - mbedtls_ctr_drbg_free(&ctr_drbg); + if (key_id != 0) { + psa_destroy_key(key_id); + } if (rc != 0) { return BLE_SM_KEY_ERR; } #else - if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { + // TinyCrypt/uECC expects 64 bytes: X (32 bytes) + Y (32 bytes), no prefix + swap_buf(pk, peer_pub_key_x, 32); + swap_buf(&pk[32], peer_pub_key_y, 32); + + if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { return BLE_SM_KEY_ERR; } @@ -1735,42 +1702,38 @@ exit: static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) { int rc = BLE_SM_KEY_ERR; - mbedtls_entropy_context entropy = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_algorithm_t alg = PSA_ALG_ECDH; + psa_key_type_t key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); + psa_key_usage_t key_usage = PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT; - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_ecp_keypair_init(&keypair); - - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { - goto exit; - } - - if ((rc = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, &keypair, - mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) { - goto exit; - } - - if ((rc = mbedtls_mpi_write_binary(&keypair.MBEDTLS_PRIVATE(d), private_key, 32)) != 0) { + psa_set_key_type(&key_attributes, key_type); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, alg); + psa_set_key_usage_flags(&key_attributes, key_usage); + status = psa_generate_key(&key_attributes, &key_id); + if (status != PSA_SUCCESS) { goto exit; } + psa_reset_key_attributes(&key_attributes); size_t olen = 0; - uint8_t pub[65] = {0}; - - if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, pub, 65)) != 0) { + 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; } - memcpy(public_key, &pub[1], 64); + status = psa_export_key(key_id, private_key, 32, &olen); + if (status != PSA_SUCCESS || olen != 32) { + goto exit; + } + psa_destroy_key(key_id); + rc = 0; exit: - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); if (rc != 0) { - mbedtls_ecp_keypair_free(&keypair); return BLE_SM_KEY_ERR; } @@ -1789,7 +1752,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) swap_buf(&pub[32], &ble_sm_alg_dbg_pub_key[32], 32); swap_buf(priv, ble_sm_alg_dbg_priv_key, 32); #else - uint8_t pk[64]; + uint8_t pk[BLE_PUB_KEY_LEN]; do { #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1804,8 +1767,16 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) /* Make sure generated key isn't debug key. */ } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); +#if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS + // PSA returns 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + // Skip the 0x04 prefix when copying to pub + swap_buf(pub, &pk[1], 32); + swap_buf(&pub[32], &pk[33], 32); +#else + // tinycrypt returns 64 bytes: X (32 bytes) + Y (32 bytes), no prefix swap_buf(pub, pk, 32); swap_buf(&pub[32], &pk[32], 32); +#endif swap_in_place(priv, 32); #endif // CONFIG_BT_LE_SM_SC_DEBUG_KEYS return 0; diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index de8d8f51fcc..5eb26edc600 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -1655,24 +1655,16 @@ void esp_ble_controller_log_dump_all(bool output) #if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 +#define BLE_PUB_KEY_LEN 65 #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#include "mbedtls/aes.h" #if CONFIG_BT_LE_SM_SC -#include "mbedtls/cipher.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/cmac.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/ecp.h" - -static mbedtls_ecp_keypair keypair; +#include "psa/crypto.h" +static const char *TAG_SM_ALG = "ble_sm_alg"; #endif // CONFIG_BT_LE_SM_SC - #else #include "tinycrypt/aes.h" #include "tinycrypt/constants.h" #include "tinycrypt/utils.h" - #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" @@ -1709,84 +1701,58 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ const uint8_t *our_priv_key, uint8_t *out_dhkey) { uint8_t dh[32]; - uint8_t pk[64]; + uint8_t pk[BLE_PUB_KEY_LEN]; uint8_t priv[32]; int rc = BLE_SM_KEY_ERR; - swap_buf(pk, peer_pub_key_x, 32); - swap_buf(&pk[32], peer_pub_key_y, 32); swap_buf(priv, our_priv_key, 32); #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS - struct mbedtls_ecp_point pt = {0}, Q = {0}; - mbedtls_mpi z = {0}, d = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; - mbedtls_entropy_context entropy = {0}; + // PSA/mbedTLS expects 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + pk[0] = 0x04; // Uncompressed format for public key + swap_buf(&pk[1], peer_pub_key_x, 32); + swap_buf(&pk[33], peer_pub_key_y, 32); - uint8_t pub[65] = {0}; - /* Hardcoded first byte of pub key for MBEDTLS_ECP_PF_UNCOMPRESSED */ - pub[0] = 0x04; - memcpy(&pub[1], pk, 64); - - /* Initialize the required structures here */ - mbedtls_ecp_point_init(&pt); - mbedtls_ecp_point_init(&Q); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_entropy_init(&entropy); - mbedtls_mpi_init(&d); - mbedtls_mpi_init(&z); - - /* Below 3 steps are to validate public key on curve secp256r1 */ - if (mbedtls_ecp_group_load(&keypair.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1) != 0) { + psa_key_id_t key_id = 0; + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); + status = psa_import_key(&key_attributes, priv, 32, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG_SM_ALG, "Failed to import key: %d", status); + goto exit; + } + psa_reset_key_attributes(&key_attributes); + size_t output_len = 0; + status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, pk, BLE_PUB_KEY_LEN, dh, sizeof(dh), &output_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG_SM_ALG, "Failed to perform raw key agreement: %d", status); goto exit; } - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &pt, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_ecp_check_pubkey(&keypair.MBEDTLS_PRIVATE(grp), &pt) != 0) { - goto exit; - } - - /* Set PRNG */ - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { - goto exit; - } - - /* Prepare point Q from pub key */ - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &Q, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_mpi_read_binary(&d, priv, 32) != 0) { - goto exit; - } - - rc = mbedtls_ecdh_compute_shared(&keypair.MBEDTLS_PRIVATE(grp), &z, &Q, &d, - mbedtls_ctr_drbg_random, &ctr_drbg); - if (rc != 0) { - goto exit; - } - - rc = mbedtls_mpi_write_binary(&z, dh, 32); - if (rc != 0) { + if (output_len != 32) { + ESP_LOGE(TAG_SM_ALG, "Unexpected output length: %zu", output_len); goto exit; } + rc = 0; exit: - mbedtls_ecp_point_free(&pt); - mbedtls_mpi_free(&z); - mbedtls_mpi_free(&d); - mbedtls_ecp_point_free(&Q); - mbedtls_entropy_free(&entropy); - mbedtls_ctr_drbg_free(&ctr_drbg); + if (key_id != 0) { + psa_destroy_key(key_id); + } if (rc != 0) { return BLE_SM_KEY_ERR; } #else - if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { + // TinyCrypt/uECC expects 64 bytes: X (32 bytes) + Y (32 bytes), no prefix + swap_buf(pk, peer_pub_key_x, 32); + swap_buf(&pk[32], peer_pub_key_y, 32); + + if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { return BLE_SM_KEY_ERR; } @@ -1804,42 +1770,38 @@ exit: static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) { int rc = BLE_SM_KEY_ERR; - mbedtls_entropy_context entropy = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_algorithm_t alg = PSA_ALG_ECDH; + psa_key_type_t key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); + psa_key_usage_t key_usage = PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT; - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_ecp_keypair_init(&keypair); - - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { - goto exit; - } - - if ((rc = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, &keypair, - mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) { - goto exit; - } - - if ((rc = mbedtls_mpi_write_binary(&keypair.MBEDTLS_PRIVATE(d), private_key, 32)) != 0) { + psa_set_key_type(&key_attributes, key_type); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, alg); + psa_set_key_usage_flags(&key_attributes, key_usage); + status = psa_generate_key(&key_attributes, &key_id); + if (status != PSA_SUCCESS) { goto exit; } + psa_reset_key_attributes(&key_attributes); size_t olen = 0; - uint8_t pub[65] = {0}; - - if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, pub, 65)) != 0) { + 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; } - memcpy(public_key, &pub[1], 64); + status = psa_export_key(key_id, private_key, 32, &olen); + if (status != PSA_SUCCESS || olen != 32) { + goto exit; + } + psa_destroy_key(key_id); + rc = 0; exit: - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); if (rc != 0) { - mbedtls_ecp_keypair_free(&keypair); return BLE_SM_KEY_ERR; } @@ -1858,7 +1820,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) swap_buf(&pub[32], &ble_sm_alg_dbg_pub_key[32], 32); swap_buf(priv, ble_sm_alg_dbg_priv_key, 32); #else - uint8_t pk[64]; + uint8_t pk[BLE_PUB_KEY_LEN]; do { #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1873,8 +1835,16 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) /* Make sure generated key isn't debug key. */ } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); +#if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS + // PSA returns 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + // Skip the 0x04 prefix when copying to pub + swap_buf(pub, &pk[1], 32); + swap_buf(&pub[32], &pk[33], 32); +#else + // tinycrypt returns 64 bytes: X (32 bytes) + Y (32 bytes), no prefix swap_buf(pub, pk, 32); swap_buf(&pub[32], &pk[32], 32); +#endif swap_in_place(priv, 32); #endif // CONFIG_BT_LE_SM_SC_DEBUG_KEYS return 0; diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index ffa419c6e0f..3b7c5be0113 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -1605,19 +1605,11 @@ void esp_ble_controller_log_dump_all(bool output) #if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 +#define BLE_PUB_KEY_LEN 65 #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#include "mbedtls/aes.h" #if CONFIG_BT_LE_SM_SC -#include "mbedtls/cipher.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/cmac.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/ecp.h" - -static mbedtls_ecp_keypair keypair; +#include "psa/crypto.h" #endif // CONFIG_BT_LE_SM_SC - #else #include "tinycrypt/aes.h" #include "tinycrypt/constants.h" @@ -1659,84 +1651,52 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ const uint8_t *our_priv_key, uint8_t *out_dhkey) { uint8_t dh[32]; - uint8_t pk[64]; + uint8_t pk[BLE_PUB_KEY_LEN]; uint8_t priv[32]; int rc = BLE_SM_KEY_ERR; - swap_buf(pk, peer_pub_key_x, 32); - swap_buf(&pk[32], peer_pub_key_y, 32); swap_buf(priv, our_priv_key, 32); #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS - struct mbedtls_ecp_point pt = {0}, Q = {0}; - mbedtls_mpi z = {0}, d = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; - mbedtls_entropy_context entropy = {0}; + // PSA/mbedTLS expects 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + pk[0] = 0x04; // Uncompressed format for public key + swap_buf(&pk[1], peer_pub_key_x, 32); + swap_buf(&pk[33], peer_pub_key_y, 32); - uint8_t pub[65] = {0}; - /* Hardcoded first byte of pub key for MBEDTLS_ECP_PF_UNCOMPRESSED */ - pub[0] = 0x04; - memcpy(&pub[1], pk, 64); - - /* Initialize the required structures here */ - mbedtls_ecp_point_init(&pt); - mbedtls_ecp_point_init(&Q); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_entropy_init(&entropy); - mbedtls_mpi_init(&d); - mbedtls_mpi_init(&z); - - /* Below 3 steps are to validate public key on curve secp256r1 */ - if (mbedtls_ecp_group_load(&keypair.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1) != 0) { + psa_key_id_t key_id = 0; + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); + status = psa_import_key(&key_attributes, priv, 32, &key_id); + if (status != PSA_SUCCESS) { + goto exit; + } + psa_reset_key_attributes(&key_attributes); + size_t output_len = 0; + status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, pk, BLE_PUB_KEY_LEN, dh, sizeof(dh), &output_len); + if (status != PSA_SUCCESS) { goto exit; } - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &pt, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_ecp_check_pubkey(&keypair.MBEDTLS_PRIVATE(grp), &pt) != 0) { - goto exit; - } - - /* Set PRNG */ - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { - goto exit; - } - - /* Prepare point Q from pub key */ - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &Q, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_mpi_read_binary(&d, priv, 32) != 0) { - goto exit; - } - - rc = mbedtls_ecdh_compute_shared(&keypair.MBEDTLS_PRIVATE(grp), &z, &Q, &d, - mbedtls_ctr_drbg_random, &ctr_drbg); - if (rc != 0) { - goto exit; - } - - rc = mbedtls_mpi_write_binary(&z, dh, 32); - if (rc != 0) { + if (output_len != 32) { goto exit; } + rc = 0; exit: - mbedtls_ecp_point_free(&pt); - mbedtls_mpi_free(&z); - mbedtls_mpi_free(&d); - mbedtls_ecp_point_free(&Q); - mbedtls_entropy_free(&entropy); - mbedtls_ctr_drbg_free(&ctr_drbg); if (rc != 0) { return BLE_SM_KEY_ERR; } #else - if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) { + // TinyCrypt/uECC expects 64 bytes: X (32 bytes) + Y (32 bytes), no prefix + swap_buf(pk, peer_pub_key_x, 32); + swap_buf(&pk[32], peer_pub_key_y, 32); + + if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { return BLE_SM_KEY_ERR; } @@ -1754,42 +1714,39 @@ exit: static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) { int rc = BLE_SM_KEY_ERR; - mbedtls_entropy_context entropy = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_algorithm_t alg = PSA_ALG_ECDH; + psa_key_type_t key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); + psa_key_usage_t key_usage = PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT; - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_ecp_keypair_init(&keypair); - - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { - goto exit; - } - - if ((rc = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, &keypair, - mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) { - goto exit; - } - - if ((rc = mbedtls_mpi_write_binary(&keypair.MBEDTLS_PRIVATE(d), private_key, 32)) != 0) { + psa_set_key_type(&key_attributes, key_type); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, alg); + psa_set_key_usage_flags(&key_attributes, key_usage); + status = psa_generate_key(&key_attributes, &key_id); + if (status != PSA_SUCCESS) { goto exit; } + psa_reset_key_attributes(&key_attributes); size_t olen = 0; - uint8_t pub[65] = {0}; - - if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, pub, 65)) != 0) { + 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; } - memcpy(public_key, &pub[1], 64); + status = psa_export_key(key_id, private_key, 32, &olen); + if (status != PSA_SUCCESS || olen != 32) { + goto exit; + } + + psa_destroy_key(key_id); + rc = 0; exit: - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); if (rc != 0) { - mbedtls_ecp_keypair_free(&keypair); return BLE_SM_KEY_ERR; } @@ -1808,7 +1765,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) swap_buf(&pub[32], &ble_sm_alg_dbg_pub_key[32], 32); swap_buf(priv, ble_sm_alg_dbg_priv_key, 32); #else - uint8_t pk[64]; + uint8_t pk[BLE_PUB_KEY_LEN]; do { #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS @@ -1823,8 +1780,16 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) /* Make sure generated key isn't debug key. */ } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); +#if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS + // PSA returns 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + // Skip the 0x04 prefix when copying to pub + swap_buf(pub, &pk[1], 32); + swap_buf(&pub[32], &pk[33], 32); +#else + // tinycrypt returns 64 bytes: X (32 bytes) + Y (32 bytes), no prefix swap_buf(pub, pk, 32); swap_buf(&pub[32], &pk[32], 32); +#endif swap_in_place(priv, 32); #endif // CONFIG_BT_LE_SM_SC_DEBUG_KEYS return 0; diff --git a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c index a322c0ab867..ec584b8933a 100644 --- a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c @@ -19,7 +19,7 @@ #include "device/controller.h" #if CONFIG_MBEDTLS_HARDWARE_AES -#include "mbedtls/aes.h" +#include "psa/crypto.h" #endif #include @@ -2580,26 +2580,47 @@ int bt_mesh_encrypt_le(const uint8_t key[16], const uint8_t plaintext[16], BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); #if CONFIG_MBEDTLS_HARDWARE_AES - mbedtls_aes_context ctx = {0}; - - mbedtls_aes_init(&ctx); - sys_memcpy_swap(tmp, key, 16); + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING; + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - if (mbedtls_aes_setkey_enc(&ctx, tmp, 128) != 0) { - mbedtls_aes_free(&ctx); + status = psa_import_key(&attributes, tmp, 16, &key_id); + if (status != PSA_SUCCESS) { + BT_ERR("psa_import_key failed with status %d", status); + return -EINVAL; + } + psa_reset_key_attributes(&attributes); + + status = psa_cipher_encrypt_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + BT_ERR("psa_cipher_encrypt_setup failed with status %d", status); + psa_destroy_key(key_id); + return -EINVAL; + } + size_t output_length = 0; + status = psa_cipher_update(&operation, plaintext, 16, enc_data, 16, &output_length); + if (status != PSA_SUCCESS || output_length != 16) { + BT_ERR("psa_cipher_update failed with status %d", status); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); return -EINVAL; } - sys_memcpy_swap(tmp, plaintext, 16); - - if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, - tmp, enc_data) != 0) { - mbedtls_aes_free(&ctx); + status = psa_cipher_finish(&operation, enc_data + output_length, 16 - output_length, &output_length); + if (status != PSA_SUCCESS) { + BT_ERR("psa_cipher_finish failed with status %d", status); return -EINVAL; } - mbedtls_aes_free(&ctx); + psa_destroy_key(key_id); + #else /* CONFIG_MBEDTLS_HARDWARE_AES */ struct tc_aes_key_sched_struct s = {0}; @@ -2629,22 +2650,44 @@ int bt_mesh_encrypt_be(const uint8_t key[16], const uint8_t plaintext[16], BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); #if CONFIG_MBEDTLS_HARDWARE_AES - mbedtls_aes_context ctx = {0}; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING; + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - mbedtls_aes_init(&ctx); - - if (mbedtls_aes_setkey_enc(&ctx, key, 128) != 0) { - mbedtls_aes_free(&ctx); + status = psa_import_key(&attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + BT_ERR("psa_import_key failed with status %d", status); return -EINVAL; } - if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, - plaintext, enc_data) != 0) { - mbedtls_aes_free(&ctx); + status = psa_cipher_encrypt_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + BT_ERR("psa_cipher_encrypt_setup failed with status %d", status); + psa_destroy_key(key_id); + return -EINVAL; + } + size_t output_length = 0; + status = psa_cipher_update(&operation, plaintext, 16, enc_data, 16, &output_length); + if (status != PSA_SUCCESS || output_length != 16) { + BT_ERR("psa_cipher_update failed with status %d", status); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); return -EINVAL; } - mbedtls_aes_free(&ctx); + status = psa_cipher_finish(&operation, enc_data + output_length, 16 - output_length, &output_length); + if (status != PSA_SUCCESS) { + BT_ERR("psa_cipher_finish failed with status %d", status); + return -EINVAL; + } + + psa_destroy_key(key_id); #else /* CONFIG_MBEDTLS_HARDWARE_AES */ struct tc_aes_key_sched_struct s = {0}; diff --git a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c index 1992fb87b3c..18613b36fe1 100644 --- a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c @@ -11,8 +11,7 @@ #include "btc/btc_task.h" #include "osi/alarm.h" -#include "mbedtls/aes.h" -#include "mbedtls/ecp.h" +#include "psa/crypto.h" #include "host/ble_hs.h" #include "host/ble_uuid.h" @@ -2665,39 +2664,29 @@ const uint8_t *bt_mesh_pub_key_get(void) bool bt_mesh_check_public_key(const uint8_t key[64]) { - struct mbedtls_ecp_point pt = {0}; - mbedtls_ecp_group grp = {0}; - bool rc = false; + psa_status_t status = PSA_SUCCESS; uint8_t pub[65] = {0}; /* Hardcoded first byte of pub key for MBEDTLS_ECP_PF_UNCOMPRESSED */ pub[0] = 0x04; memcpy(&pub[1], key, 64); - /* Initialize the required structures here */ - mbedtls_ecp_point_init(&pt); - mbedtls_ecp_group_init(&grp); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&attributes, 256); - /* Below 3 steps are to validate public key on curve secp256r1 */ - if (mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1) != 0) { - goto exit; + status = psa_import_key(&attributes, pub, sizeof(pub), &key_id); + if (status != PSA_SUCCESS) { + BT_ERR("Failed to import public key, status: %d", status); + return false; } + psa_reset_key_attributes(&attributes); + psa_destroy_key(key_id); - if (mbedtls_ecp_point_read_binary(&grp, &pt, pub, 65) != 0) { - goto exit; - } - - if (mbedtls_ecp_check_pubkey(&grp, &pt) != 0) { - goto exit; - } - - rc = true; - -exit: - mbedtls_ecp_point_free(&pt); - mbedtls_ecp_group_free(&grp); - return rc; - + return true; } int ble_sm_alg_gen_dhkey(uint8_t *peer_pub_key_x, uint8_t *peer_pub_key_y, @@ -2719,26 +2708,46 @@ int bt_mesh_encrypt_le(const uint8_t key[16], const uint8_t plaintext[16], BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); #if CONFIG_MBEDTLS_HARDWARE_AES - mbedtls_aes_context ctx = {0}; - - mbedtls_aes_init(&ctx); - sys_memcpy_swap(tmp, key, 16); + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING; + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - if (mbedtls_aes_setkey_enc(&ctx, tmp, 128) != 0) { - mbedtls_aes_free(&ctx); + status = psa_import_key(&attributes, tmp, 16, &key_id); + if (status != PSA_SUCCESS) { + BT_ERR("psa_import_key failed with status %d", status); + return -EINVAL; + } + psa_reset_key_attributes(&attributes); + + status = psa_cipher_encrypt_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + BT_ERR("psa_cipher_encrypt_setup failed with status %d", status); + psa_destroy_key(key_id); + return -EINVAL; + } + size_t output_length = 0; + status = psa_cipher_update(&operation, plaintext, 16, enc_data, 16, &output_length); + if (status != PSA_SUCCESS || output_length != 16) { + BT_ERR("psa_cipher_update failed with status %d", status); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); return -EINVAL; } - sys_memcpy_swap(tmp, plaintext, 16); - - if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, - tmp, enc_data) != 0) { - mbedtls_aes_free(&ctx); + status = psa_cipher_finish(&operation, enc_data + output_length, 16 - output_length, &output_length); + if (status != PSA_SUCCESS) { + BT_ERR("psa_cipher_finish failed with status %d", status); return -EINVAL; } - mbedtls_aes_free(&ctx); + psa_destroy_key(key_id); #else /* CONFIG_MBEDTLS_HARDWARE_AES */ struct tc_aes_key_sched_struct s = {0}; @@ -2768,22 +2777,45 @@ int bt_mesh_encrypt_be(const uint8_t key[16], const uint8_t plaintext[16], BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); #if CONFIG_MBEDTLS_HARDWARE_AES - mbedtls_aes_context ctx = {0}; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING; + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); - mbedtls_aes_init(&ctx); - - if (mbedtls_aes_setkey_enc(&ctx, key, 128) != 0) { - mbedtls_aes_free(&ctx); + status = psa_import_key(&attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + BT_ERR("psa_import_key failed with status %d", status); return -EINVAL; } - if (mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, - plaintext, enc_data) != 0) { - mbedtls_aes_free(&ctx); + status = psa_cipher_encrypt_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + BT_ERR("psa_cipher_encrypt_setup failed with status %d", status); + psa_destroy_key(key_id); + return -EINVAL; + } + size_t output_length = 0; + status = psa_cipher_update(&operation, plaintext, 16, enc_data, 16, &output_length); + if (status != PSA_SUCCESS || output_length != 16) { + BT_ERR("psa_cipher_update failed with status %d", status); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); return -EINVAL; } - mbedtls_aes_free(&ctx); + status = psa_cipher_finish(&operation, enc_data + output_length, 16 - output_length, &output_length); + if (status != PSA_SUCCESS) { + BT_ERR("psa_cipher_finish failed with status %d", status); + psa_destroy_key(key_id); + return -EINVAL; + } + + psa_destroy_key(key_id); #else /* CONFIG_MBEDTLS_HARDWARE_AES */ struct tc_aes_key_sched_struct s = {0}; diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 686728c09ec..872f3c1849a 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 686728c09ec94a86afeeb58a936a9f6a4ab5fd83 +Subproject commit 872f3c1849abfb124fa53d345cd9786f949d3b57 diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index d8f5dd84cca..427607ca4df 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -26,7 +26,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 && MBEDTLS_PK_RSA_ALT_SUPPORT + depends on ESP_TLS_USING_MBEDTLS && SOC_DIG_SIGN_SUPPORTED default y help Enable use of the Digital Signature Peripheral for ESP-TLS.The DS peripheral @@ -76,9 +76,7 @@ menu "ESP-TLS" bool "Enable PSK verification" select MBEDTLS_PSK_MODES if ESP_TLS_USING_MBEDTLS select MBEDTLS_KEY_EXCHANGE_PSK if ESP_TLS_USING_MBEDTLS - select MBEDTLS_KEY_EXCHANGE_DHE_PSK if ESP_TLS_USING_MBEDTLS && MBEDTLS_DHM_C select MBEDTLS_KEY_EXCHANGE_ECDHE_PSK if ESP_TLS_USING_MBEDTLS && MBEDTLS_ECDH_C - select MBEDTLS_KEY_EXCHANGE_RSA_PSK if ESP_TLS_USING_MBEDTLS help Enable support for pre shared key ciphers, supported for both mbedTLS as well as wolfSSL TLS library. diff --git a/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c b/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c index 64e82462880..8589164cc5f 100644 --- a/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c +++ b/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c @@ -10,9 +10,9 @@ #include "sdkconfig.h" __attribute__((unused)) static const char *TAG = "esp_crypto"; #ifdef CONFIG_ESP_TLS_USING_MBEDTLS -#include "mbedtls/sha1.h" #include "mbedtls/base64.h" #include "mbedtls/error.h" +#include "psa/crypto.h" #define _esp_crypto_sha1 esp_crypto_sha1_mbedtls #define _esp_crypto_base64_encode esp_crypto_bas64_encode_mbedtls #elif CONFIG_ESP_TLS_USING_WOLFSSL @@ -28,29 +28,25 @@ static int esp_crypto_sha1_mbedtls( const unsigned char *input, unsigned char output[20]) { #if CONFIG_MBEDTLS_SHA1_C || CONFIG_MBEDTLS_HARDWARE_SHA - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_sha1_context ctx; + psa_hash_operation_t ctx = PSA_HASH_OPERATION_INIT; - mbedtls_sha1_init(&ctx); - - if ((ret = mbedtls_sha1_starts(&ctx)) != 0) { + psa_status_t status = psa_hash_setup(&ctx, PSA_ALG_SHA_1); + if (status != PSA_SUCCESS) { goto exit; } - if ((ret = mbedtls_sha1_update(&ctx, input, ilen)) != 0) { + if ((status = psa_hash_update(&ctx, input, ilen)) != PSA_SUCCESS) { goto exit; } - if ((ret = mbedtls_sha1_finish(&ctx, output)) != 0) { + size_t hash_len; + if ((status = psa_hash_finish(&ctx, output, 20, &hash_len)) != PSA_SUCCESS) { goto exit; } exit: - mbedtls_sha1_free(&ctx); - if (ret != 0) { - ESP_LOGE(TAG, "Error in calculating sha1 sum , Returned 0x%02X", ret); - } - return ret; + psa_hash_abort(&ctx); + return status == PSA_SUCCESS ? 0 : -1; #else ESP_LOGE(TAG, "Please enable CONFIG_MBEDTLS_SHA1_C or CONFIG_MBEDTLS_HARDWARE_SHA to support SHA1 operations"); return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index 1e2c57340f6..a72c33ff055 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -15,8 +15,6 @@ #include "mbedtls/x509_crt.h" #ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS #include "mbedtls/ssl_ticket.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #endif #elif CONFIG_ESP_TLS_USING_WOLFSSL #include "wolfssl/wolfcrypt/settings.h" @@ -246,11 +244,6 @@ typedef struct esp_tls_cfg { * @brief Data structures necessary to support TLS session tickets according to RFC5077 */ typedef struct esp_tls_server_session_ticket_ctx { - mbedtls_entropy_context entropy; /*!< mbedTLS entropy context structure */ - - mbedtls_ctr_drbg_context ctr_drbg; /*!< mbedTLS ctr drbg context structure. - CTR_DRBG is deterministic random - bit generation based on AES-256 */ mbedtls_ssl_ticket_context ticket_ctx; /*!< Session ticket generation context */ } esp_tls_server_session_ticket_ctx_t; #endif diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 73bee131a32..42f31565abd 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -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" @@ -47,6 +48,9 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki); static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki); #endif /* CONFIG_ESP_TLS_USE_DS_PERIPHERAL */ +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" + static const char *TAG = "esp-tls-mbedtls"; static mbedtls_x509_crt *global_cacert = NULL; @@ -118,30 +122,9 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const int ret; esp_err_t esp_ret = ESP_FAIL; -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - psa_status_t status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Failed to initialize PSA crypto, returned %d", (int) status); - return esp_ret; - } -#endif // CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - tls->server_fd.fd = tls->sockfd; mbedtls_ssl_init(&tls->ssl); - mbedtls_ctr_drbg_init(&tls->ctr_drbg); mbedtls_ssl_config_init(&tls->conf); - mbedtls_entropy_init(&tls->entropy); - - if ((ret = mbedtls_ctr_drbg_seed(&tls->ctr_drbg, - mbedtls_entropy_func, &tls->entropy, NULL, 0)) != 0) { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04X", -ret); - mbedtls_print_error_msg(ret); - ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_MBEDTLS, -ret); - esp_ret = ESP_ERR_MBEDTLS_CTR_DRBG_SEED_FAILED; - goto exit; - } - - mbedtls_ssl_conf_rng(&tls->conf, mbedtls_ctr_drbg_random, &tls->ctr_drbg); #if CONFIG_MBEDTLS_DYNAMIC_BUFFER tls->esp_tls_dyn_buf_strategy = ((esp_tls_cfg_t *)cfg)->esp_tls_dyn_buf_strategy; @@ -202,7 +185,6 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const exit: esp_mbedtls_cleanup(tls); return esp_ret; - } void *esp_mbedtls_get_ssl_context(esp_tls_t *tls) @@ -506,30 +488,54 @@ void esp_mbedtls_cleanup(esp_tls_t *tls) mbedtls_x509_crt_free(&tls->clientcert); #ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL - if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_RSA_ALT) { - mbedtls_rsa_alt_context *rsa_alt = tls->clientkey.MBEDTLS_PRIVATE(pk_ctx); - if (rsa_alt && rsa_alt->key != NULL) { - mbedtls_rsa_free(rsa_alt->key); - mbedtls_free(rsa_alt->key); - rsa_alt->key = NULL; + if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_RSASSA_PSS) { + mbedtls_rsa_context *rsa = tls->clientkey.MBEDTLS_PRIVATE(pk_ctx); + if (rsa != NULL) { + mbedtls_rsa_free(rsa); + mbedtls_free(rsa); + rsa = NULL; } + tls->clientkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; } // Similar cleanup for server key - if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_RSA_ALT) { - mbedtls_rsa_alt_context *rsa_alt = tls->serverkey.MBEDTLS_PRIVATE(pk_ctx); - if (rsa_alt && rsa_alt->key != NULL) { - mbedtls_rsa_free(rsa_alt->key); - mbedtls_free(rsa_alt->key); - rsa_alt->key = NULL; + if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_RSASSA_PSS) { + mbedtls_rsa_context *rsa = tls->serverkey.MBEDTLS_PRIVATE(pk_ctx); + if (rsa != NULL) { + mbedtls_rsa_free(rsa); + mbedtls_free(rsa); + rsa = NULL; } + tls->serverkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; + } +#endif + +#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN + /* In mbedtls v4.0, ECDSA keys require manual cleanup of the keypair structure */ + if (mbedtls_pk_get_type(&tls->clientkey) == MBEDTLS_PK_ECDSA) { + mbedtls_ecp_keypair *keypair = tls->clientkey.MBEDTLS_PRIVATE(pk_ctx); + if (keypair != NULL) { + mbedtls_ecp_keypair_free(keypair); + mbedtls_free(keypair); + keypair = NULL; + } + tls->clientkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; + } + + // Similar cleanup for server key + if (mbedtls_pk_get_type(&tls->serverkey) == MBEDTLS_PK_ECDSA) { + mbedtls_ecp_keypair *keypair = tls->serverkey.MBEDTLS_PRIVATE(pk_ctx); + if (keypair != NULL) { + mbedtls_ecp_keypair_free(keypair); + mbedtls_free(keypair); + keypair = NULL; + } + tls->serverkey.MBEDTLS_PRIVATE(pk_ctx) = NULL; } #endif mbedtls_pk_free(&tls->clientkey); - mbedtls_entropy_free(&tls->entropy); mbedtls_ssl_config_free(&tls->conf); - mbedtls_ctr_drbg_free(&tls->ctr_drbg); mbedtls_ssl_free(&tls->ssl); #ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT atcab_release(); @@ -614,8 +620,7 @@ static esp_err_t set_pki_context(esp_tls_t *tls, const esp_tls_pki_t *pki) #endif if (pki->privkey_pem_buf != NULL) { ret = mbedtls_pk_parse_key(pki->pk_key, pki->privkey_pem_buf, pki->privkey_pem_bytes, - pki->privkey_password, pki->privkey_password_len, - mbedtls_ctr_drbg_random, &tls->ctr_drbg); + pki->privkey_password, pki->privkey_password_len); } else { return ESP_ERR_INVALID_ARG; } @@ -683,22 +688,11 @@ esp_err_t esp_mbedtls_server_session_ticket_ctx_init(esp_tls_server_session_tick if (!ctx) { return ESP_ERR_INVALID_ARG; } - mbedtls_ctr_drbg_init(&ctx->ctr_drbg); - mbedtls_entropy_init(&ctx->entropy); mbedtls_ssl_ticket_init(&ctx->ticket_ctx); int ret; esp_err_t esp_ret; - if ((ret = mbedtls_ctr_drbg_seed(&ctx->ctr_drbg, - mbedtls_entropy_func, &ctx->entropy, NULL, 0)) != 0) { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04X", -ret); - mbedtls_print_error_msg(ret); - esp_ret = ESP_ERR_MBEDTLS_CTR_DRBG_SEED_FAILED; - goto exit; - } - - if((ret = mbedtls_ssl_ticket_setup(&ctx->ticket_ctx, - mbedtls_ctr_drbg_random, &ctx->ctr_drbg, - MBEDTLS_CIPHER_AES_256_GCM, + if ((ret = mbedtls_ssl_ticket_setup(&ctx->ticket_ctx, + PSA_ALG_GCM, PSA_KEY_TYPE_AES, 256, CONFIG_ESP_TLS_SERVER_SESSION_TICKET_TIMEOUT)) != 0) { ESP_LOGE(TAG, "mbedtls_ssl_ticket_setup returned -0x%04X", -ret); mbedtls_print_error_msg(ret); @@ -715,8 +709,6 @@ void esp_mbedtls_server_session_ticket_ctx_free(esp_tls_server_session_ticket_ct { if (ctx) { mbedtls_ssl_ticket_free(&ctx->ticket_ctx); - mbedtls_ctr_drbg_init(&ctx->ctr_drbg); - mbedtls_entropy_free(&ctx->entropy); } } #endif @@ -958,12 +950,6 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t #endif /* CONFIG_MBEDTLS_SSL_RENEGOTIATION */ #endif /* CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS */ -#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 -#if CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS || CONFIG_MBEDTLS_DYNAMIC_BUFFER - mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(&tls->conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED); -#endif -#endif - if (cfg->crt_bundle_attach != NULL) { #ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE ESP_LOGD(TAG, "Use certificate bundle"); @@ -1381,6 +1367,13 @@ static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, const void *pki) #endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */ #ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL + +int esp_mbedtls_ds_can_do(mbedtls_pk_type_t type) +{ + ESP_LOGI(TAG, "esp_mbedtls_ds_can_do called with type %d", type); + return type == MBEDTLS_PK_RSA || type == MBEDTLS_PK_RSASSA_PSS; +} + static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki) { int ret = -1; @@ -1391,15 +1384,23 @@ static esp_err_t esp_mbedtls_init_pk_ctx_for_ds(const void *pki) return ESP_ERR_NO_MEM; } mbedtls_rsa_init(rsakey); - if ((ret = mbedtls_pk_setup_rsa_alt(((const esp_tls_pki_t*)pki)->pk_key, rsakey, NULL, esp_ds_rsa_sign, - esp_ds_get_keylen )) != 0) { - ESP_LOGE(TAG, "Error in mbedtls_pk_setup_rsa_alt, returned -0x%04X", -ret); - mbedtls_print_error_msg(ret); + esp_tls_pki_t *pki_l = (esp_tls_pki_t *) pki; + mbedtls_pk_context *pk_context = (mbedtls_pk_context *) pki_l->pk_key; + mbedtls_pk_info_t *esp_ds_pk_info = calloc(1, sizeof(mbedtls_pk_info_t)); + if (esp_ds_pk_info == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for mbedtls_pk_info_t"); + ret = ESP_ERR_NO_MEM; mbedtls_rsa_free(rsakey); free(rsakey); - ret = ESP_FAIL; goto exit; } + + esp_ds_pk_info->sign_func = esp_ds_rsa_sign_alt; + esp_ds_pk_info->get_bitlen = esp_ds_get_keylen_alt; + esp_ds_pk_info->can_do = esp_mbedtls_ds_can_do; + esp_ds_pk_info->type = MBEDTLS_PK_RSASSA_PSS; + pk_context->pk_info = esp_ds_pk_info; + pk_context->pk_ctx = rsakey; ret = esp_ds_init_data_ctx(((const esp_tls_pki_t*)pki)->esp_ds_data); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize DS parameters from nvs"); diff --git a/components/esp-tls/private_include/esp_tls_private.h b/components/esp-tls/private_include/esp_tls_private.h index 728b538d13a..a4cbc9d4bdd 100644 --- a/components/esp-tls/private_include/esp_tls_private.h +++ b/components/esp-tls/private_include/esp_tls_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,8 +20,6 @@ #include "mbedtls/net_sockets.h" #include "mbedtls/esp_debug.h" #include "mbedtls/ssl.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #include "mbedtls/error.h" #ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS #include "mbedtls/ssl_ticket.h" @@ -38,12 +36,6 @@ struct esp_tls { #ifdef CONFIG_ESP_TLS_USING_MBEDTLS mbedtls_ssl_context ssl; /*!< TLS/SSL context */ - mbedtls_entropy_context entropy; /*!< mbedTLS entropy context structure */ - - mbedtls_ctr_drbg_context ctr_drbg; /*!< mbedTLS ctr drbg context structure. - CTR_DRBG is deterministic random - bit generation based on AES-256 */ - mbedtls_ssl_config conf; /*!< TLS/SSL configuration to be shared between mbedtls_ssl_context structures */ diff --git a/components/esp-tls/test_apps/main/app_main.c b/components/esp-tls/test_apps/main/app_main.c index 2c1a5935abc..6a5f0351795 100644 --- a/components/esp-tls/test_apps/main/app_main.c +++ b/components/esp-tls/test_apps/main/app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unity.h" -#include "mbedtls/aes.h" #include "memory_checks.h" #include "soc/soc_caps.h" #if SOC_SHA_SUPPORT_PARALLEL_ENG @@ -16,12 +15,16 @@ #include "sha/sha_core.h" #endif #include "esp_newlib.h" - +#include "psa/crypto.h" #if SOC_SHA_SUPPORT_SHA512 #define SHA_TYPE SHA2_512 #else #define SHA_TYPE SHA2_256 #endif //SOC_SHA_SUPPORT_SHA512 +#include + + +#define CALL_SZ (32 * 1024) /* setUp runs before every test */ void setUp(void) @@ -34,23 +37,31 @@ void setUp(void) esp_sha(SHA_TYPE, input_buffer, sizeof(input_buffer), output_buffer); #endif // SOC_SHA_SUPPORTED -#if SOC_AES_SUPPORTED // Execute mbedtls_aes_init operation to allocate AES interrupt // allocation memory which is considered as leak otherwise - const uint8_t plaintext[16] = {0}; - uint8_t ciphertext[16]; - const uint8_t key[16] = { 0 }; - mbedtls_aes_context ctx; - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plaintext, ciphertext); - mbedtls_aes_free(&ctx); -#endif // SOC_AES_SUPPORTED + uint8_t iv[16]; + uint8_t key[16]; + memset(iv, 0xEE, 16); + memset(key, 0x44, 16); + + uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(buf); + psa_key_id_t key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_import_key(&attributes, key, sizeof(key), &key_id); + + size_t output_length = 0; + psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, buf, CALL_SZ, buf, CALL_SZ, &output_length); + heap_caps_free(buf); + psa_destroy_key(key_id); test_utils_record_free_mem(); TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_GENERAL)); - } /* tearDown runs after every test */ diff --git a/components/esp_eth/test_apps/sdkconfig.defaults b/components/esp_eth/test_apps/sdkconfig.defaults new file mode 100644 index 00000000000..900304b0a29 --- /dev/null +++ b/components/esp_eth/test_apps/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096 diff --git a/components/esp_http_client/lib/http_auth.c b/components/esp_http_client/lib/http_auth.c index 8670e2140de..b51b8fc3966 100644 --- a/components/esp_http_client/lib/http_auth.c +++ b/components/esp_http_client/lib/http_auth.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,6 @@ #include "sys/socket.h" #include "esp_rom_md5.h" #include "esp_tls_crypto.h" -#include "mbedtls/sha256.h" #include "esp_log.h" #include "esp_check.h" @@ -20,6 +19,8 @@ #include "http_utils.h" #include "http_auth.h" +#include "psa/crypto.h" + #define MD5_MAX_LEN (33) #define SHA256_LEN (32) #define SHA256_HEX_LEN (65) @@ -72,7 +73,6 @@ static int md5_printf(char *md, const char *fmt, ...) */ static int sha256_sprintf(char *sha, const char *fmt, ...) { - unsigned char *buf; unsigned char digest[SHA256_LEN]; int len, i; @@ -85,19 +85,26 @@ static int sha256_sprintf(char *sha, const char *fmt, ...) } int ret = 0; - mbedtls_sha256_context sha256; - mbedtls_sha256_init(&sha256); - if (mbedtls_sha256_starts(&sha256, 0) != 0) { - goto exit; - } - if (mbedtls_sha256_update(&sha256, buf, len) != 0) { - goto exit; - } - if (mbedtls_sha256_finish(&sha256, digest) != 0) { + psa_status_t status; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + + status = psa_hash_setup(&operation, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { goto exit; } - for (i = 0; i < 32; ++i) { + status = psa_hash_update(&operation, buf, len); + if (status != PSA_SUCCESS) { + goto exit; + } + + size_t hash_length; + status = psa_hash_finish(&operation, digest, sizeof(digest), &hash_length); + if (status != PSA_SUCCESS || hash_length != SHA256_LEN) { + goto exit; + } + + for (i = 0; i < SHA256_LEN; ++i) { sprintf(&sha[i * 2], "%02x", (unsigned int)digest[i]); } sha[SHA256_HEX_LEN - 1] = '\0'; @@ -105,7 +112,7 @@ static int sha256_sprintf(char *sha, const char *fmt, ...) exit: free(buf); - mbedtls_sha256_free(&sha256); + psa_hash_abort(&operation); va_end(ap); return ret; } diff --git a/components/esp_http_server/src/httpd_ws.c b/components/esp_http_server/src/httpd_ws.c index 4bffe538421..949addc674a 100644 --- a/components/esp_http_server/src/httpd_ws.c +++ b/components/esp_http_server/src/httpd_ws.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include @@ -143,37 +143,29 @@ esp_err_t httpd_ws_respond_server_handshake(httpd_req_t *req, const char *suppor ESP_LOGD(TAG, LOG_FMT("Server key before encoding: %s"), server_raw_text); - /* Generate SHA-1 first and then encode to Base64 */ - size_t key_len = strlen(server_raw_text); - -#if CONFIG_MBEDTLS_SHA1_C || CONFIG_MBEDTLS_HARDWARE_SHA - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - mbedtls_sha1_context ctx; - mbedtls_sha1_init(&ctx); - - if ((ret = mbedtls_sha1_starts(&ctx)) != 0) { - goto sha_end; - } - - if ((ret = mbedtls_sha1_update(&ctx, (uint8_t *)server_raw_text, key_len)) != 0) { - goto sha_end; - } - - if ((ret = mbedtls_sha1_finish(&ctx, server_key_hash)) != 0) { - goto sha_end; - } - -sha_end: - mbedtls_sha1_free(&ctx); - if (ret != 0) { - ESP_LOGE(TAG, "Error in calculating SHA1 sum , returned 0x%02X", ret); + /* Generate SHA-1 hash */ + psa_hash_operation_t sha1_operation = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&sha1_operation, PSA_ALG_SHA_1); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to setup SHA-1 operation"); return ESP_FAIL; } -#else - ESP_LOGE(TAG, "Please enable CONFIG_MBEDTLS_SHA1_C or CONFIG_MBEDTLS_HARDWARE_SHA to support SHA1 operations"); - return ESP_FAIL; -#endif /* CONFIG_MBEDTLS_SHA1_C || CONFIG_MBEDTLS_HARDWARE_SHA */ + status = psa_hash_update(&sha1_operation, (uint8_t *)server_raw_text, strlen(server_raw_text)); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to update SHA-1 hash"); + psa_hash_abort(&sha1_operation); + return ESP_FAIL; + } + + size_t hash_length; + status = psa_hash_finish(&sha1_operation, server_key_hash, sizeof(server_key_hash), &hash_length); + if (status != PSA_SUCCESS || hash_length != sizeof(server_key_hash)) { + ESP_LOGE(TAG, "Failed to finish SHA-1 hash"); + return ESP_FAIL; + } + + /* Encode to Base64 */ size_t encoded_len = 0; mbedtls_base64_encode((uint8_t *)server_key_encoded, sizeof(server_key_encoded), &encoded_len, server_key_hash, sizeof(server_key_hash)); diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index 6ad741688b6..35947277ee7 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -410,6 +410,8 @@ md5_vector = 0x40000610; MD5Init = 0x40000614; MD5Update = 0x40000618; MD5Final = 0x4000061c; +PROVIDE (hmac_md5_vector = 0x40000620); +PROVIDE (hmac_md5 = 0x40000624); crc32_le = 0x40000628; crc32_be = 0x4000062c; crc16_le = 0x40000630; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index f573448e7a1..3d700b8bf9b 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -518,6 +518,8 @@ md5_vector = 0x40001c50; MD5Init = 0x40001c5c; MD5Update = 0x40001c68; MD5Final = 0x40001c74; +PROVIDE (hmac_md5_vector = 0x40001c80); +PROVIDE (hmac_md5 = 0x40001c8c); crc32_le = 0x40001c98; crc32_be = 0x40001ca4; crc16_le = 0x40001cb0; diff --git a/components/esp_rom/include/esp_rom_md5.h b/components/esp_rom/include/esp_rom_md5.h index ca42faee22d..9ce96049a2d 100644 --- a/components/esp_rom/include/esp_rom_md5.h +++ b/components/esp_rom/include/esp_rom_md5.h @@ -27,7 +27,7 @@ extern "C" { * stronger message digests instead. * */ -typedef struct mbedtls_md5_context { +typedef struct md5_context { uint32_t total[2]; /*!< number of bytes processed */ uint32_t state[4]; /*!< intermediate digest state */ unsigned char buffer[64]; /*!< data block being processed */ diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 5e048324b94..a359cb228d0 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -79,6 +79,9 @@ SECONDARY: 102: init_rng in components/esp_hw_support/hw_random.c on BIT(0) # Security specific initializations SECONDARY: 103: esp_security_init in components/esp_security/src/init.c on BIT(0) +# PSA Crypto initialization (must happen after esp_security_init for hardware crypto support) +SECONDARY: 104: mbedtls_psa_crypto_init_fn in components/mbedtls/port/esp_psa_crypto_init.c on BIT(0) + # esp_sleep doesn't have init dependencies SECONDARY: 105: esp_sleep_startup_init in components/esp_hw_support/sleep_gpio.c on BIT(0) SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_clock.c on BIT(0) diff --git a/components/esp_tee/Kconfig.projbuild b/components/esp_tee/Kconfig.projbuild index 9f6682a1b88..4e6f6604f6f 100644 --- a/components/esp_tee/Kconfig.projbuild +++ b/components/esp_tee/Kconfig.projbuild @@ -12,14 +12,14 @@ menu "ESP-TEE (Trusted Execution Environment)" config SECURE_TEE_IRAM_SIZE hex "IRAM region size" default 0x8000 - range 0x5000 0xA000 + range 0x5000 0xF000 help This configuration sets the IRAM size for the TEE module. This should be 256-byte (0x100) aligned. config SECURE_TEE_DRAM_SIZE hex "DRAM region size" - default 0x4000 + default 0x5000 range 0x3000 0x7000 help This configuration sets the DRAM size for the TEE module. @@ -45,7 +45,7 @@ menu "ESP-TEE (Trusted Execution Environment)" config SECURE_TEE_IROM_SIZE hex - default 0x10000 + default 0x20000 help This should be a multiple of MMU_PAGE_SIZE. diff --git a/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c b/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c index 1ea6b724968..b998b3aade6 100644 --- a/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c +++ b/components/esp_tee/subproject/components/attestation/esp_att_utils_crypto.c @@ -14,12 +14,8 @@ #include "bootloader_sha.h" #include "esp_tee_sec_storage.h" #endif - #include "esp_random.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/ecdsa.h" -#include "mbedtls/sha256.h" - +#include "psa/crypto.h" #include "esp_attestation_utils.h" #define ECDSA_PUBKEY_PREFIX_SZ (0x02) @@ -91,8 +87,8 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair return err; } - memcpy(sign_r, sign.sign_r, sign_r_len); - memcpy(sign_s, sign.sign_s, sign_s_len); + memcpy(sign_r, sign.signature, sign_r_len); + memcpy(sign_s, sign.signature + sign_r_len, sign_s_len); return ESP_OK; } @@ -113,44 +109,34 @@ static esp_err_t gen_ecdsa_keypair_secp256r1(esp_att_ecdsa_keypair_t *keypair) memset(keypair, 0x00, sizeof(esp_att_ecdsa_keypair_t)); - int ret = -1; - esp_err_t err = ESP_FAIL; - - mbedtls_ecdsa_context ecdsa_ctx; - mbedtls_ecdsa_init(&ecdsa_ctx); - - ret = mbedtls_ecdsa_genkey(&ecdsa_ctx, MBEDTLS_ECP_DP_SECP256R1, rng_func, NULL); - if (ret != 0) { - goto exit; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA); + psa_status_t status = psa_generate_key(&key_attributes, &keypair->key_id); + if (status != PSA_SUCCESS) { + return ESP_FAIL; } - size_t pvt_len = mbedtls_mpi_size(&ecdsa_ctx.MBEDTLS_PRIVATE(d)); - ret = mbedtls_mpi_write_binary(&ecdsa_ctx.MBEDTLS_PRIVATE(d), (unsigned char *)keypair->pvt_key, pvt_len); - if (ret != 0) { - goto exit; + size_t pub_key_len = 0; + uint8_t pub_key[2 * SECP256R1_ECDSA_KEY_LEN + 1] = {0}; + status = psa_export_public_key(keypair->key_id, pub_key, sizeof(pub_key), &pub_key_len); + if (status != PSA_SUCCESS) { + return ESP_FAIL; } - size_t pubx_len = mbedtls_mpi_size(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X))); - ret = mbedtls_mpi_write_binary(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), (unsigned char *)(keypair->pub_key_x), pubx_len); - if (ret != 0) { - goto exit; + if (pub_key_len != sizeof(pub_key)) { + return ESP_ERR_INVALID_SIZE; } - size_t puby_len = mbedtls_mpi_size(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y))); - ret = mbedtls_mpi_write_binary(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), (unsigned char *)(keypair->pub_key_y), puby_len); - if (ret != 0) { - goto exit; - } + memcpy(keypair->pub_key_x, pub_key + 1, SECP256R1_ECDSA_KEY_LEN); + memcpy(keypair->pub_key_y, pub_key + 1 + SECP256R1_ECDSA_KEY_LEN, SECP256R1_ECDSA_KEY_LEN); + + psa_reset_key_attributes(&key_attributes); keypair->curve = 0; - err = ESP_OK; - -exit: - if (ret != 0) { - ESP_LOGE(TAG, "Failed to generate ECDSA keypair (-0x%X)", -ret); - } - mbedtls_ecdsa_free(&ecdsa_ctx); - return err; + return ESP_OK; } static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair, const uint8_t *digest, const size_t len, @@ -164,67 +150,21 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair return ESP_ERR_INVALID_SIZE; } - esp_err_t err = ESP_FAIL; - - mbedtls_ecp_keypair pvt_key; - mbedtls_mpi r, s; - - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - mbedtls_ecp_keypair_init(&pvt_key); - - int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &pvt_key, keypair->pvt_key, sizeof(keypair->pvt_key)); - if (ret != 0) { - goto exit; + size_t signature_len = 0; + uint8_t signature[sign_r_len + sign_s_len]; + psa_status_t status = psa_sign_hash(keypair->key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, signature, sign_r_len + sign_s_len, &signature_len); + if (status != PSA_SUCCESS) { + return ESP_FAIL; } - mbedtls_ecdsa_context ecdsa_ctx; - mbedtls_ecdsa_init(&ecdsa_ctx); - - ret = mbedtls_ecdsa_from_keypair(&ecdsa_ctx, &pvt_key); - if (ret != 0) { - goto exit; + if (signature_len != sign_r_len + sign_s_len) { + return ESP_ERR_INVALID_SIZE; } - ret = mbedtls_ecdsa_sign(&ecdsa_ctx.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa_ctx.MBEDTLS_PRIVATE(d), - digest, len, rng_func, NULL); - if (ret != 0) { - return ret; - } + memcpy(sign_r, signature, sign_r_len); + memcpy(sign_s, signature + sign_r_len, sign_s_len); - size_t r_len = mbedtls_mpi_size(&r); - if (r_len > sign_s_len) { - goto exit; - } - - ret = mbedtls_mpi_write_binary(&r, (unsigned char *)(sign_r), r_len); - if (ret != 0) { - goto exit; - } - - size_t s_len = mbedtls_mpi_size(&s); - if (s_len > sign_s_len) { - goto exit; - } - - ret = mbedtls_mpi_write_binary(&s, (unsigned char *)(sign_s), s_len); - if (ret != 0) { - goto exit; - } - - err = ESP_OK; - -exit: - if (ret != 0) { - ESP_LOGE(TAG, "Failed to generate ECDSA signature (-0x%X)", -ret); - } - - mbedtls_ecdsa_free(&ecdsa_ctx); - mbedtls_ecp_keypair_free(&pvt_key); - mbedtls_mpi_free(&s); - mbedtls_mpi_free(&r); - - return err; + return ESP_OK; } #endif @@ -241,33 +181,23 @@ esp_err_t esp_att_utils_ecdsa_get_pubkey(const esp_att_ecdsa_keypair_t *keypair, return ESP_ERR_INVALID_ARG; } - esp_err_t err = ESP_FAIL; - - size_t hexstr_len = sizeof(keypair->pub_key_x) * 2 + ECDSA_PUBKEY_PREFIX_SZ + 1; - char *hexstr = calloc(hexstr_len, sizeof(uint8_t)); - if (hexstr == NULL) { - err = ESP_ERR_NO_MEM; - goto exit; + size_t pubkey_hexstr_size = sizeof(keypair->pub_key_x) * 2 + ECDSA_PUBKEY_PREFIX_SZ + 1; + *pubkey_hexstr = calloc(pubkey_hexstr_size, sizeof(char)); + if (*pubkey_hexstr == NULL) { + return ESP_ERR_NO_MEM; } - /* Checking the parity of the y-component of the public key */ - char *pubkey_prefix = (keypair->pub_key_y[SECP256R1_ECDSA_KEY_LEN - 1] & 1) - ? ECDSA_COMPRESSED_KEY_ODD_PREFIX - : ECDSA_COMPRESSED_KEY_EVEN_PREFIX; - memcpy(hexstr, pubkey_prefix, ECDSA_PUBKEY_PREFIX_SZ); + char *pubkey_prefix = (keypair->pub_key_y[SECP256R1_ECDSA_KEY_LEN - 1] & 1) ? ECDSA_COMPRESSED_KEY_ODD_PREFIX : ECDSA_COMPRESSED_KEY_EVEN_PREFIX; + memcpy(*pubkey_hexstr, pubkey_prefix, ECDSA_PUBKEY_PREFIX_SZ); - err = esp_att_utils_hexbuf_to_hexstr(keypair->pub_key_x, sizeof(keypair->pub_key_x), - &hexstr[ECDSA_PUBKEY_PREFIX_SZ], hexstr_len - ECDSA_PUBKEY_PREFIX_SZ); + int err = esp_att_utils_hexbuf_to_hexstr(keypair->pub_key_x, sizeof(keypair->pub_key_x), *pubkey_hexstr + ECDSA_PUBKEY_PREFIX_SZ, pubkey_hexstr_size - ECDSA_PUBKEY_PREFIX_SZ); if (err != ESP_OK) { - goto exit; + free(*pubkey_hexstr); + *pubkey_hexstr = NULL; + return err; } - *pubkey_hexstr = hexstr; return ESP_OK; - -exit: - free(hexstr); - return err; } esp_err_t esp_att_utils_ecdsa_get_pubkey_digest(const esp_att_ecdsa_keypair_t *keypair, uint8_t *digest, const size_t len) @@ -277,16 +207,30 @@ esp_err_t esp_att_utils_ecdsa_get_pubkey_digest(const esp_att_ecdsa_keypair_t *k } uint8_t pubkey_c[SECP256R1_ECDSA_KEY_LEN * 2] = {0}; - memcpy(pubkey_c, keypair->pub_key_x, SECP256R1_ECDSA_KEY_LEN); - memcpy(pubkey_c + SECP256R1_ECDSA_KEY_LEN, keypair->pub_key_y, SECP256R1_ECDSA_KEY_LEN); + memcpy(pubkey_c, keypair->pub_key_x, sizeof(keypair->pub_key_x)); + memcpy(pubkey_c + SECP256R1_ECDSA_KEY_LEN, keypair->pub_key_y, sizeof(keypair->pub_key_y)); uint8_t pubkey_digest[SHA256_DIGEST_SZ]; - int ret = mbedtls_sha256((const unsigned char *)pubkey_c, sizeof(pubkey_c), pubkey_digest, false); - if (ret != 0) { - ESP_LOGE(TAG, "Failed to calculate pubkey digest (-%X)", -ret); + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { return ESP_FAIL; } + status = psa_hash_update(&hash_op, pubkey_c, sizeof(pubkey_c)); + if (status != PSA_SUCCESS) { + return ESP_FAIL; + } + size_t pubkey_digest_len = 0; + status = psa_hash_finish(&hash_op, pubkey_digest, len, &pubkey_digest_len); + if (status != PSA_SUCCESS) { + return ESP_FAIL; + } + + if (pubkey_digest_len != len) { + return ESP_ERR_INVALID_SIZE; + } + memcpy(digest, pubkey_digest, len); return ESP_OK; } diff --git a/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c b/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c index 0954122bde2..c8f238b12e3 100644 --- a/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c +++ b/components/esp_tee/subproject/components/attestation/esp_att_utils_json.c @@ -14,11 +14,7 @@ #include "bootloader_sha.h" #include "esp_tee_sec_storage.h" #endif - #include "esp_random.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/ecdsa.h" -#include "mbedtls/sha256.h" #include "json_generator.h" #include "esp_attestation_utils.h" diff --git a/components/esp_tee/subproject/components/attestation/esp_att_utils_part_info.c b/components/esp_tee/subproject/components/attestation/esp_att_utils_part_info.c index bdab8b5fd04..c6aff792ef5 100644 --- a/components/esp_tee/subproject/components/attestation/esp_att_utils_part_info.c +++ b/components/esp_tee/subproject/components/attestation/esp_att_utils_part_info.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,9 +37,8 @@ #include "esp32c6/rom/secure_boot.h" #endif #endif - -#include "mbedtls/sha256.h" - +#define DECLARE_PRIVATE_IDENTIFIERS +#include "psa/crypto.h" #include "bootloader_flash_priv.h" #include "esp_attestation_utils.h" @@ -50,7 +49,7 @@ static const char *TAG = "esp_att_utils"; /* Forward declaration */ static esp_err_t read_partition(uint32_t offset, void *buf, size_t size); -esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest); +esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len); static esp_err_t get_active_app_part_pos(esp_partition_pos_t *pos); static esp_err_t get_active_tee_part_pos(esp_partition_pos_t *pos); @@ -78,7 +77,7 @@ static esp_err_t read_partition(uint32_t offset, void *buf, size_t size) return (esp_err_t)esp_tee_flash_read(offset, buf, size, true); } -esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest) +esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len) { if (digest == NULL) { return ESP_ERR_INVALID_ARG; @@ -87,12 +86,9 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t uint32_t mmu_free_pages_count = esp_tee_flash_mmap_get_free_pages(); uint32_t partial_image_len = mmu_free_pages_count * CONFIG_MMU_PAGE_SIZE; - mbedtls_sha256_context ctx; - mbedtls_sha256_init(&ctx); - - int ret = mbedtls_sha256_starts(&ctx, false); - if (ret != 0) { - mbedtls_sha256_free(&ctx); + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { return ESP_FAIL; } @@ -100,18 +96,27 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t uint32_t mmap_len = MIN(len, partial_image_len); const void *image = esp_tee_flash_mmap(flash_offset, mmap_len); if (image == NULL) { - mbedtls_sha256_free(&ctx); + psa_hash_abort(&hash_op); + return ESP_FAIL; + } + status = psa_hash_update(&hash_op, image, mmap_len); + if (status != PSA_SUCCESS) { + psa_hash_abort(&hash_op); return ESP_FAIL; } - mbedtls_sha256_update(&ctx, image, mmap_len); esp_tee_flash_munmap(image); flash_offset += mmap_len; len -= mmap_len; } - mbedtls_sha256_finish(&ctx, digest); - mbedtls_sha256_free(&ctx); + size_t digest_size = 0; + status = psa_hash_finish(&hash_op, digest, digest_len, &digest_size); + if (status != PSA_SUCCESS) { + psa_hash_abort(&hash_op); + return ESP_FAIL; + } + return ESP_OK; } @@ -154,7 +159,7 @@ static esp_err_t read_partition(uint32_t offset, void *buf, size_t size) return esp_flash_read(NULL, buf, offset, size); } -esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest) +esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len) { if (digest == NULL) { return ESP_ERR_INVALID_ARG; @@ -165,11 +170,10 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t uint32_t mmu_free_pages_count = bootloader_mmap_get_free_pages(); uint32_t partial_image_len = mmu_free_pages_count * CONFIG_MMU_PAGE_SIZE; - mbedtls_sha256_context sha256_ctx; - mbedtls_sha256_init(&sha256_ctx); - - if (mbedtls_sha256_starts(&sha256_ctx, false) != 0) { - goto exit; + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { + return ESP_FAIL; } while (len > 0) { @@ -178,7 +182,9 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t if (image == NULL) { goto exit; } - if (mbedtls_sha256_update(&sha256_ctx, image, mmap_len) != 0) { + status = psa_hash_update(&hash_op, image, mmap_len); + if (status != PSA_SUCCESS) { + psa_hash_abort(&hash_op); goto exit; } bootloader_munmap(image); @@ -187,13 +193,16 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t len -= mmap_len; } - if (mbedtls_sha256_finish(&sha256_ctx, digest) != 0) { + size_t digest_size = 0; + status = psa_hash_finish(&hash_op, digest, digest_len, &digest_size); + if (status != PSA_SUCCESS) { + psa_hash_abort(&hash_op); goto exit; } err = ESP_OK; exit: - mbedtls_sha256_free(&sha256_ctx); + psa_hash_abort(&hash_op); return err; } @@ -283,7 +292,7 @@ static esp_err_t get_part_digest(const esp_partition_pos_t *pos, esp_att_part_di return ESP_ERR_NO_MEM; } - err = get_flash_contents_sha256(pos->offset, image_len, digest); + err = get_flash_contents_sha256(pos->offset, image_len, digest, digest_len); if (err != ESP_OK) { goto exit; } diff --git a/components/esp_tee/subproject/components/attestation/esp_attestation.c b/components/esp_tee/subproject/components/attestation/esp_attestation.c index 2fa56295f12..a62be9c3678 100644 --- a/components/esp_tee/subproject/components/attestation/esp_attestation.c +++ b/components/esp_tee/subproject/components/attestation/esp_attestation.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,9 +14,7 @@ #include "esp_efuse.h" #include "esp_efuse_table.h" #include "hal/efuse_hal.h" - -#include "mbedtls/sha256.h" - +#include "psa/crypto.h" #include "esp_attestation.h" #include "esp_attestation_utils.h" @@ -63,33 +61,28 @@ static esp_err_t fetch_device_id(uint8_t *devid_buf) goto exit; } - mbedtls_sha256_context ctx; - mbedtls_sha256_init(&ctx); - - int ret = mbedtls_sha256_starts(&ctx, false); - if (ret != 0) { - mbedtls_sha256_free(&ctx); - err = ESP_FAIL; - goto exit; + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { + return ESP_FAIL; } - ret = mbedtls_sha256_update(&ctx, (const unsigned char *)mac_addr, sizeof(mac_addr)); - if (ret != 0) { - mbedtls_sha256_free(&ctx); - err = ESP_FAIL; - goto exit; + status = psa_hash_update(&hash_op, mac_addr, sizeof(mac_addr)); + if (status != PSA_SUCCESS) { + return ESP_FAIL; } - uint8_t digest[SHA256_DIGEST_SZ] = {0}; - ret = mbedtls_sha256_finish(&ctx, digest); - if (ret != 0) { - mbedtls_sha256_free(&ctx); - err = ESP_FAIL; - goto exit; + size_t digest_len = 0; + status = psa_hash_finish(&hash_op, devid_buf, SHA256_DIGEST_SZ, &digest_len); + if (status != PSA_SUCCESS) { + return ESP_FAIL; } - memcpy(devid_buf, digest, SHA256_DIGEST_SZ); - mbedtls_sha256_free(&ctx); + if (digest_len != SHA256_DIGEST_SZ) { + return ESP_ERR_INVALID_SIZE; + } + + return ESP_OK; exit: return err; @@ -211,12 +204,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id, memset(token_buf, 0x00, token_buf_size); - mbedtls_sha256_context ctx; - mbedtls_sha256_init(&ctx); - - int ret = mbedtls_sha256_starts(&ctx, false); - if (ret != 0) { - mbedtls_sha256_free(&ctx); + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { return ESP_FAIL; } @@ -236,9 +226,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id, } json_gen_push_object_str(&jstr, "header", hdr_json); - ret = mbedtls_sha256_update(&ctx, (const unsigned char *)hdr_json, hdr_len - 1); - if (ret != 0) { - mbedtls_sha256_free(&ctx); + status = psa_hash_update(&hash_op, (const unsigned char *)hdr_json, hdr_len - 1); + if (status != PSA_SUCCESS) { + psa_hash_abort(&hash_op); return ESP_FAIL; } free(hdr_json); @@ -253,9 +243,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id, } json_gen_push_object_str(&jstr, "eat", eat_json); - ret = mbedtls_sha256_update(&ctx, (const unsigned char *)eat_json, eat_len - 1); - if (ret != 0) { - mbedtls_sha256_free(&ctx); + status = psa_hash_update(&hash_op, (const unsigned char *)eat_json, eat_len - 1); + if (status != PSA_SUCCESS) { + psa_hash_abort(&hash_op); return ESP_FAIL; } free(eat_json); @@ -269,20 +259,20 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id, } json_gen_push_object_str(&jstr, "public_key", pubkey_json); - ret = mbedtls_sha256_update(&ctx, (const unsigned char *)pubkey_json, pubkey_len - 1); - if (ret != 0) { - mbedtls_sha256_free(&ctx); + status = psa_hash_update(&hash_op, (const unsigned char *)pubkey_json, pubkey_len - 1); + if (status != PSA_SUCCESS) { + psa_hash_abort(&hash_op); return ESP_FAIL; } free(pubkey_json); uint8_t digest[SHA256_DIGEST_SZ] = {0}; - ret = mbedtls_sha256_finish(&ctx, digest); - if (ret != 0) { - mbedtls_sha256_free(&ctx); + size_t digest_len = 0; + status = psa_hash_finish(&hash_op, digest, sizeof(digest), &digest_len); + if (status != PSA_SUCCESS) { + psa_hash_abort(&hash_op); return ESP_FAIL; } - mbedtls_sha256_free(&ctx); char *sign_json = NULL; int sign_len = -1; diff --git a/components/esp_tee/subproject/components/attestation/private_include/esp_attestation_utils.h b/components/esp_tee/subproject/components/attestation/private_include/esp_attestation_utils.h index 31963a248a3..e26f45ea88e 100644 --- a/components/esp_tee/subproject/components/attestation/private_include/esp_attestation_utils.h +++ b/components/esp_tee/subproject/components/attestation/private_include/esp_attestation_utils.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,8 @@ #include "esp_attestation.h" +#include "psa/crypto.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h b/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h index 379ecc86534..b9cf001238c 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h +++ b/components/esp_tee/subproject/components/tee_sec_storage/include/esp_tee_sec_storage.h @@ -79,8 +79,7 @@ typedef struct { * */ typedef struct { - uint8_t sign_r[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< R component */ - uint8_t sign_s[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< S component */ + uint8_t signature[MAX_ECDSA_SUPPORTED_KEY_LEN * 2]; /*!< Signature */ } __attribute__((__packed__)) esp_tee_sec_storage_ecdsa_sign_t; #if ESP_TEE_BUILD && !(__DOXYGEN__) diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c index 0ad68fd8699..2c24ee9bd5b 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage.c @@ -15,15 +15,11 @@ #include "spi_flash_mmap.h" #if SOC_HMAC_SUPPORTED #include "esp_hmac.h" -#include "esp_hmac_pbkdf2.h" -#else -#include "mbedtls/md.h" #endif - -#include "mbedtls/aes.h" -#include "mbedtls/gcm.h" -#include "mbedtls/sha256.h" -#include "mbedtls/ecdsa.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include "esp_hmac_pbkdf2.h" +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" #include "esp_rom_sys.h" #include "nvs.h" @@ -134,12 +130,6 @@ static int buffer_hexdump(const char *label, const void *buffer, size_t length) return 0; } -static int rand_func(void *rng_state, unsigned char *output, size_t len) -{ - esp_fill_random(output, len); - return 0; -} - #if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_cfg_t *cfg) { @@ -312,66 +302,89 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t return -1; } - mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_SECP256R1; - size_t key_len = ECDSA_SECP256R1_KEY_LEN; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { #if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN - curve_id = MBEDTLS_ECP_DP_SECP192R1; - key_len = ECDSA_SECP192R1_KEY_LEN; + psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8); #else ESP_LOGE(TAG, "Unsupported key-type!"); return -1; #endif } - - ESP_LOGD(TAG, "Generating ECDSA key for curve %d...", curve_id); - - mbedtls_ecdsa_context ctxECDSA; - mbedtls_ecdsa_init(&ctxECDSA); - - int ret = mbedtls_ecdsa_genkey(&ctxECDSA, curve_id, rand_func, NULL); - if (ret != 0) { + psa_status_t status = psa_generate_key(&key_attributes, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to generate ECDSA key: %ld", status); goto exit; } - uint8_t *priv_key = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ? - keyctx->ecdsa_secp256r1.priv_key : + size_t priv_key_len = 0; + size_t pub_key_len = 0; + + /* Use the correct union member based on key type */ + uint8_t *priv_key_buf = NULL; + size_t priv_key_buf_size = 0; + uint8_t *pub_key_buf = NULL; + size_t pub_key_buf_size = 0; + + if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { #if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN - keyctx->ecdsa_secp192r1.priv_key; -#else - NULL; + priv_key_buf = keyctx->ecdsa_secp192r1.priv_key; + priv_key_buf_size = sizeof(keyctx->ecdsa_secp192r1.priv_key); + pub_key_buf = keyctx->ecdsa_secp192r1.pub_key; + pub_key_buf_size = sizeof(keyctx->ecdsa_secp192r1.pub_key); #endif + } else { + priv_key_buf = keyctx->ecdsa_secp256r1.priv_key; + priv_key_buf_size = sizeof(keyctx->ecdsa_secp256r1.priv_key); + pub_key_buf = keyctx->ecdsa_secp256r1.pub_key; + pub_key_buf_size = sizeof(keyctx->ecdsa_secp256r1.pub_key); + } - uint8_t *pub_key = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ? - keyctx->ecdsa_secp256r1.pub_key : -#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN - keyctx->ecdsa_secp192r1.pub_key; -#else - NULL; -#endif - - ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), pub_key, key_len); - if (ret != 0) { + status = psa_export_key(key_id, priv_key_buf, priv_key_buf_size, &priv_key_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to export ECDSA private key: %ld", status); goto exit; } - ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), pub_key + key_len, key_len); - if (ret != 0) { + /* PSA exports public key with 0x04 prefix (65 bytes for secp256r1, 49 bytes for secp192r1) + * We need to strip the prefix and store only X and Y coordinates (64 bytes for secp256r1, 48 bytes for secp192r1) + * Use fixed-size array to avoid VLA issues with goto statements + */ + uint8_t pub_key_with_prefix[(2 * ECDSA_SECP256R1_KEY_LEN) + 1]; /* Max size: 65 bytes for secp256r1 */ + size_t pub_key_len_with_prefix = 0; + size_t expected_pub_key_len_with_prefix = pub_key_buf_size + 1; + + status = psa_export_public_key(key_id, pub_key_with_prefix, sizeof(pub_key_with_prefix), &pub_key_len_with_prefix); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to export ECDSA public key: %ld", status); goto exit; } - ret = mbedtls_mpi_write_binary(&ctxECDSA.MBEDTLS_PRIVATE(d), priv_key, key_len); - if (ret != 0) { - goto exit; + /* Strip the 0x04 prefix if present */ + if (pub_key_len_with_prefix == expected_pub_key_len_with_prefix && pub_key_with_prefix[0] == 0x04) { + memcpy(pub_key_buf, pub_key_with_prefix + 1, pub_key_buf_size); + pub_key_len = pub_key_buf_size; + } else { + /* Fallback: copy directly if format is unexpected (should not happen with PSA) */ + ESP_LOGW(TAG, "Unexpected public key format, copying directly"); + size_t copy_len = (pub_key_len_with_prefix < pub_key_buf_size) ? pub_key_len_with_prefix : pub_key_buf_size; + memcpy(pub_key_buf, pub_key_with_prefix, copy_len); + pub_key_len = copy_len; } - buffer_hexdump("Private key", priv_key, key_len); - buffer_hexdump("Public key", pub_key, key_len * 2); + buffer_hexdump("Private key", priv_key_buf, priv_key_len); + buffer_hexdump("Public key", pub_key_buf, pub_key_len); exit: - mbedtls_ecdsa_free(&ctxECDSA); - return ret; + psa_destroy_key(key_id); + psa_reset_key_attributes(&key_attributes); + return status == PSA_SUCCESS ? 0 : -1; } static int generate_aes256_key(sec_stg_key_t *keyctx) @@ -460,68 +473,47 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf return ESP_ERR_INVALID_STATE; } - mbedtls_mpi r, s; - mbedtls_ecp_keypair priv_key; - mbedtls_ecdsa_context sign_ctx; - - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); - mbedtls_ecp_keypair_init(&priv_key); - mbedtls_ecdsa_init(&sign_ctx); - - size_t key_len = 0; - int ret = -1; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + uint8_t *priv_key = NULL; + size_t priv_key_len = 0; if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) { - ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &priv_key, keyctx.ecdsa_secp256r1.priv_key, sizeof(keyctx.ecdsa_secp256r1.priv_key)); - key_len = ECDSA_SECP256R1_KEY_LEN; + psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8); + priv_key = keyctx.ecdsa_secp256r1.priv_key; + priv_key_len = sizeof(keyctx.ecdsa_secp256r1.priv_key); #if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN } else if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) { - ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP192R1, &priv_key, keyctx.ecdsa_secp192r1.priv_key, sizeof(keyctx.ecdsa_secp192r1.priv_key)); - key_len = ECDSA_SECP192R1_KEY_LEN; + psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8); + priv_key = keyctx.ecdsa_secp192r1.priv_key; + priv_key_len = sizeof(keyctx.ecdsa_secp192r1.priv_key); #endif } - if (ret != 0) { - err = ESP_FAIL; - goto exit; - } - - ret = mbedtls_ecdsa_from_keypair(&sign_ctx, &priv_key); - if (ret != 0) { + psa_status_t status = psa_import_key(&key_attributes, priv_key, priv_key_len, &key_id); + if (status != PSA_SUCCESS) { err = ESP_FAIL; + ESP_LOGE(TAG, "Failed to import ECDSA private key: %ld", status); goto exit; } ESP_LOGD(TAG, "Generating ECDSA signature..."); - - ret = mbedtls_ecdsa_sign(&sign_ctx.MBEDTLS_PRIVATE(grp), &r, &s, &sign_ctx.MBEDTLS_PRIVATE(d), hash, hlen, - rand_func, NULL); - if (ret != 0) { - ESP_LOGE(TAG, "Error generating signature: %d", ret); - err = ESP_FAIL; - goto exit; - } - - memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t)); - ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len); - if (ret == 0) { - ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, key_len); - } - - if (ret != 0) { - memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t)); + size_t signature_len = 0; + status = psa_sign_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, hlen, out_sign->signature, sizeof(out_sign->signature), &signature_len); + if (status != PSA_SUCCESS) { err = ESP_FAIL; + ESP_LOGE(TAG, "Failed to generate ECDSA signature: %ld", status); goto exit; } err = ESP_OK; exit: - mbedtls_ecdsa_free(&sign_ctx); - mbedtls_ecp_keypair_free(&priv_key); - mbedtls_mpi_free(&s); - mbedtls_mpi_free(&r); + psa_destroy_key(key_id); + psa_reset_key_attributes(&key_attributes); return err; } @@ -540,6 +532,20 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg sec_stg_key_t keyctx; size_t keyctx_len = sizeof(keyctx); + + /* Read key from storage first before accessing its fields */ + err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to read key from secure storage"); + return err; + } + + if (keyctx.type != cfg->type) { + ESP_LOGE(TAG, "Key type mismatch"); + return ESP_ERR_INVALID_STATE; + } + + /* Now determine the public key source and length based on key type */ uint8_t *pub_key_src = NULL; size_t pub_key_len = 0; @@ -559,17 +565,6 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg return ESP_ERR_INVALID_ARG; } - err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to read key from secure storage"); - return err; - } - - if (keyctx.type != cfg->type) { - ESP_LOGE(TAG, "Key type mismatch"); - return ESP_ERR_INVALID_STATE; - } - memcpy(out_pubkey->pub_x, pub_key_src, pub_key_len); memcpy(out_pubkey->pub_y, pub_key_src + pub_key_len, pub_key_len); @@ -737,7 +732,7 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2 goto exit; } - ret = mbedtls_ecp_keypair_calc_public(&keypair, rand_func, NULL); + ret = mbedtls_ecp_keypair_calc_public(&keypair, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE); if (ret != 0) { err = ESP_FAIL; goto exit; @@ -745,16 +740,16 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2 ret = mbedtls_ecdsa_sign(&keypair.MBEDTLS_PRIVATE(grp), &r, &s, &keypair.MBEDTLS_PRIVATE(d), hash, hlen, - rand_func, NULL); + mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE); if (ret != 0) { err = ESP_FAIL; goto exit; } memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t)); - ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len); + ret = mbedtls_mpi_write_binary(&r, out_sign->signature, key_len); if (ret == 0) { - ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, key_len); + ret = mbedtls_mpi_write_binary(&s, out_sign->signature + key_len, key_len); } if (ret != 0) { diff --git a/components/esp_tee/subproject/main/common/syscall_stubs.c b/components/esp_tee/subproject/main/common/syscall_stubs.c index 14c36dfc1ff..9ed7e86cf5b 100644 --- a/components/esp_tee/subproject/main/common/syscall_stubs.c +++ b/components/esp_tee/subproject/main/common/syscall_stubs.c @@ -54,6 +54,12 @@ ssize_t _write_r(struct _reent *r, int fd, const void *ptr, size_t len) return -1; } +ssize_t _open_r(struct _reent *r, const char *path, int flags, int mode) +{ + errno = ENOSYS; + return -1; +} + int _getpid_r(struct _reent *r) { return 1; @@ -180,14 +186,24 @@ int __cxa_thread_atexit(void (*func)(void *), void *arg, void *dso) return 0; } -#if CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C61 void *_sbrk(ptrdiff_t incr) { return (void *) -1; } -#endif void esp_tee_include_syscalls_impl(void) { } + +int _unlink_r(struct _reent *r, const char *path) +{ + errno = ENOSYS; + return -1; +} + +int _rename_r(struct _reent *r, const char *src, const char *dst) +{ + errno = ENOSYS; + return -1; +} diff --git a/components/esp_tee/subproject/main/core/esp_tee_init.c b/components/esp_tee/subproject/main/core/esp_tee_init.c index d1e6ca662cb..d42e155f579 100644 --- a/components/esp_tee/subproject/main/core/esp_tee_init.c +++ b/components/esp_tee/subproject/main/core/esp_tee_init.c @@ -22,6 +22,8 @@ #include "esp_app_desc.h" #endif +#include "psa/crypto.h" + /* TEE symbols */ extern uint32_t _tee_stack; extern uint32_t _tee_bss_start; @@ -154,6 +156,13 @@ void __attribute__((noreturn)) esp_tee_init(uint32_t ree_entry_addr, uint32_t re } ESP_FAULT_ASSERT(err == ESP_OK); + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to initialize PSA Crypto! (0x%08x)", status); + abort(); + } + ESP_FAULT_ASSERT(status == PSA_SUCCESS); + /* Initializing the secure storage */ err = esp_tee_sec_storage_init(); if (err != ESP_OK) { diff --git a/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in index 314c55388af..d0742e27a19 100644 --- a/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32c5/esp_tee.ld.in @@ -214,3 +214,8 @@ ASSERT ((_tee_iram_end <= _tee_dram_start), "Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required."); ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000), "Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required."); +/* MMU Page Alignment Checks */ +ASSERT ((CONFIG_SECURE_TEE_IROM_SIZE % 0x10000) == 0, + "Error: SECURE_TEE_IROM_SIZE must be a multiple of MMU_PAGE_SIZE (0x10000/64KB)!"); +ASSERT ((CONFIG_SECURE_TEE_DROM_SIZE % 0x10000) == 0, + "Error: SECURE_TEE_DROM_SIZE must be a multiple of MMU_PAGE_SIZE (0x10000/64KB)!"); diff --git a/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in index f36768407cb..2c9ed0d9917 100644 --- a/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in @@ -219,3 +219,8 @@ ASSERT ((_tee_iram_end <= _tee_dram_start), "Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required."); ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000), "Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required."); +/* MMU Page Alignment Checks */ +ASSERT ((CONFIG_SECURE_TEE_IROM_SIZE % CONFIG_MMU_PAGE_SIZE) == 0, + "Error: SECURE_TEE_IROM_SIZE must be a multiple of MMU_PAGE_SIZE (CONFIG_MMU_PAGE_SIZE)!"); +ASSERT ((CONFIG_SECURE_TEE_DROM_SIZE % CONFIG_MMU_PAGE_SIZE) == 0, + "Error: SECURE_TEE_DROM_SIZE must be a multiple of MMU_PAGE_SIZE (CONFIG_MMU_PAGE_SIZE)!"); diff --git a/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_ota.c b/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_ota.c index aadabe9ff4a..d167061cc83 100644 --- a/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_ota.c +++ b/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_ota.c @@ -230,7 +230,7 @@ static void init_ota_sem(void) static int create_ota_task(const char *url, const char *task_name, void (*ota_task)(void *)) { init_ota_sem(); - if (xTaskCreate(ota_task, task_name, configMINIMAL_STACK_SIZE * 3, (void *)url, 5, NULL) != pdPASS) { + if (xTaskCreate(ota_task, task_name, configMINIMAL_STACK_SIZE * 4, (void *)url, 5, NULL) != pdPASS) { ESP_LOGE(TAG, "Task creation failed for %s", task_name); return ESP_FAIL; } diff --git a/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_sec_str.c b/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_sec_str.c index 6d81b8f2ef9..25fb6ef49f9 100644 --- a/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_sec_str.c +++ b/components/esp_tee/test_apps/tee_cli_app/main/tee_srv_sec_str.c @@ -14,9 +14,7 @@ #include "esp_console.h" #include "argtable3/argtable3.h" -#include "mbedtls/ecp.h" -#include "mbedtls/ecdsa.h" -#include "mbedtls/sha256.h" +#include "psa/crypto.h" #include "esp_tee_sec_storage.h" #include "example_tee_srv.h" @@ -91,57 +89,33 @@ static esp_err_t verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, esp_err_t err = ESP_FAIL; - mbedtls_mpi r, s; - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); - mbedtls_ecdsa_context ecdsa_context; - mbedtls_ecdsa_init(&ecdsa_context); + uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN + 1]; + pub_key[0] = 0x04; + memcpy(pub_key + 1, pubkey->pub_x, ECDSA_SECP256R1_KEY_LEN); + memcpy(pub_key + 1 + ECDSA_SECP256R1_KEY_LEN, pubkey->pub_y, ECDSA_SECP256R1_KEY_LEN); - int ret = mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); - if (ret != 0) { + psa_status_t status = psa_import_key(&key_attributes, pub_key, sizeof(pub_key), &key_id); + if (status != PSA_SUCCESS) { goto exit; } - size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P); - - ret = mbedtls_mpi_read_binary(&r, sign->sign_r, plen); - if (ret != 0) { + status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, sizeof(sign->signature)); + if (status != PSA_SUCCESS) { goto exit; } - - ret = mbedtls_mpi_read_binary(&s, sign->sign_s, plen); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s); - if (ret != 0) { - goto exit; - } - err = ESP_OK; exit: - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - mbedtls_ecdsa_free(&ecdsa_context); - + if (key_id) { + psa_destroy_key(key_id); + } + psa_reset_key_attributes(&key_attributes); return err; } @@ -161,8 +135,10 @@ static int get_msg_sha256(int argc, char **argv) const char *msg = (const char *)cmd_get_msg_sha256_args.msg->sval[0]; uint8_t msg_digest[SHA256_DIGEST_SZ]; - int ret = mbedtls_sha256((const unsigned char *)msg, strlen(msg), msg_digest, false); - if (ret != 0) { + size_t msg_len = strlen(msg); + size_t digest_len = 0; + psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t *)msg, msg_len, msg_digest, sizeof(msg_digest), &digest_len); + if (status != PSA_SUCCESS) { ESP_LOGE(TAG, "Failed to calculate message hash!"); return ESP_FAIL; } diff --git a/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.minimal_tee b/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.minimal_tee index 8fcb3a7614a..9597a7c75a2 100644 --- a/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.minimal_tee +++ b/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.minimal_tee @@ -5,8 +5,8 @@ CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5 # Reducing TEE I/DRAM sizes # 24KB CONFIG_SECURE_TEE_IRAM_SIZE=0x6000 -# 12KB -CONFIG_SECURE_TEE_DRAM_SIZE=0x3000 +# 16KB +CONFIG_SECURE_TEE_DRAM_SIZE=0x4000 # Disable TEE logs (also disable all panic logs) CONFIG_SECURE_TEE_DEBUG_MODE=n diff --git a/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.release b/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.release index e96f96e949c..d89f4ebd8fc 100644 --- a/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.release +++ b/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.release @@ -1,6 +1,8 @@ # Reducing TEE I/DRAM sizes # 28KB CONFIG_SECURE_TEE_IRAM_SIZE=0x7000 +# 20KB +CONFIG_SECURE_TEE_DRAM_SIZE=0x5000 # TEE Secure Storage: Release mode CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y diff --git a/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.sb_fe b/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.sb_fe index 54cfec34a03..64b7dc33d2f 100644 --- a/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.sb_fe +++ b/components/esp_tee/test_apps/tee_cli_app/sdkconfig.ci.sb_fe @@ -18,4 +18,4 @@ CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5 # Increasing TEE DRAM size # 18KB -CONFIG_SECURE_TEE_DRAM_SIZE=0x4800 +CONFIG_SECURE_TEE_DRAM_SIZE=0x5000 diff --git a/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt b/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt index f38d3ffc802..a4410f1f9b9 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt +++ b/components/esp_tee/test_apps/tee_test_fw/main/CMakeLists.txt @@ -21,26 +21,30 @@ endif() set(mbedtls_test_srcs_dir "${idf_path}/components/mbedtls/test_apps/main") -# AES +#AES if(CONFIG_SOC_AES_SUPPORTED) - list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes.c" - "${mbedtls_test_srcs_dir}/test_aes_gcm.c" - "${mbedtls_test_srcs_dir}/test_aes_perf.c") + 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 if(CONFIG_SOC_SHA_SUPPORTED) - 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") + 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 + +#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") diff --git a/components/esp_tee/test_apps/tee_test_fw/main/app_main.c b/components/esp_tee/test_apps/tee_test_fw/main/app_main.c index 2e720900b9d..02b83d6fdfa 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/app_main.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,10 +9,64 @@ #include "nvs_flash.h" #include "unity.h" #include "memory_checks.h" +#include "psa/crypto.h" +#if SOC_SHA_SUPPORT_PARALLEL_ENG +#include "sha/sha_parallel_engine.h" +#else +#include "sha/sha_core.h" +#endif +#include "bignum_impl.h" /* setUp runs before every test */ void setUp(void) { +#if SOC_SHA_SUPPORTED + // Execute esp_sha operation to allocate internal SHA semaphore (in case of ESP32) + // and initial DMA setup memory which is considered as leaked otherwise + const uint8_t input_buffer[64] = {0}; + uint8_t output_buffer[64]; +#if SOC_SHA_SUPPORT_SHA1 + esp_sha(SHA1, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA1 +#if SOC_SHA_SUPPORT_SHA256 + esp_sha(SHA2_256, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA256 +#if SOC_SHA_SUPPORT_SHA512 + esp_sha(SHA2_512, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA512 +#endif // SOC_SHA_SUPPORTED + +#if defined(CONFIG_MBEDTLS_HARDWARE_MPI) + esp_mpi_enable_hardware_hw_op(); + esp_mpi_disable_hardware_hw_op(); +#endif // CONFIG_MBEDTLS_HARDWARE_MPI + +#if SOC_AES_SUPPORTED + // Execute mbedtls_aes_init operation to allocate AES interrupt + // allocation memory which is considered as leak otherwise + const uint8_t plaintext[16] = {0}; + uint8_t ciphertext[32]; + const uint8_t key[16] = { 0 }; + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + status = psa_import_key(&attributes, key, sizeof(key), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + size_t output_len = 0; + status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, plaintext, sizeof(plaintext), ciphertext, sizeof(ciphertext), &output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + const uint8_t plaintext_long[256] = {0}; + uint8_t ciphertext_long[272]; + output_len = 0; + status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, plaintext_long, sizeof(plaintext_long), ciphertext_long, sizeof(ciphertext_long), &output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + psa_destroy_key(key_id); +#endif // SOC_AES_SUPPORTED test_utils_record_free_mem(); test_utils_set_leak_level(CONFIG_UNITY_CRITICAL_LEAK_LEVEL_GENERAL, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL); test_utils_set_leak_level(CONFIG_UNITY_WARN_LEAK_LEVEL_GENERAL, ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_GENERAL); diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_att.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_att.c index dc010d2cc49..5b551f8efbd 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_att.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_att.c @@ -7,10 +7,8 @@ #include "esp_log.h" #include "esp_heap_caps.h" - -#include "mbedtls/ecp.h" -#include "mbedtls/ecdsa.h" -#include "mbedtls/sha256.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include "psa/crypto.h" #include "esp_tee.h" #include "esp_tee_attestation.h" @@ -24,6 +22,7 @@ /* Note: negative value here so that assert message prints a grep-able error hex value (mbedTLS uses -N for error codes) */ #define TEST_ASSERT_MBEDTLS_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X)) +#define TEST_ASSERT_PSA_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X)) #define SHA256_DIGEST_SZ (32) #define ECDSA_SECP256R1_KEY_LEN (32) @@ -165,19 +164,13 @@ static void prehash_token_data(const char *token_json, uint8_t *digest, size_t l char *eat_str = cJSON_PrintUnformatted(eat); char *public_key_str = cJSON_PrintUnformatted(public_key); - mbedtls_sha256_context sha256_ctx; - - mbedtls_sha256_init(&sha256_ctx); - - TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_starts(&sha256_ctx, false)); - - TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)header_str, strlen(header_str))); - TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)eat_str, strlen(eat_str))); - TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)public_key_str, strlen(public_key_str))); - - TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_finish(&sha256_ctx, digest)); - - mbedtls_sha256_free(&sha256_ctx); + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + TEST_ASSERT_PSA_OK(psa_hash_setup(&operation, PSA_ALG_SHA_256)); + size_t digest_len = 0; + TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)header_str, strlen(header_str))); + TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)eat_str, strlen(eat_str))); + TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)public_key_str, strlen(public_key_str))); + TEST_ASSERT_PSA_OK(psa_hash_finish(&operation, digest, SHA256_DIGEST_SZ, &digest_len)); free(public_key_str); free(eat_str); @@ -239,13 +232,13 @@ static void fetch_signature(const char *token_json, esp_tee_sec_storage_ecdsa_si uint8_t *sign_r_buf = NULL; size_t sign_r_buf_sz = 0; hexstr_to_bytes(sign_r->valuestring, &sign_r_buf, &sign_r_buf_sz); - memcpy(sign_ctx->sign_r, sign_r_buf, sign_r_buf_sz); + memcpy(sign_ctx->signature, sign_r_buf, sign_r_buf_sz); free(sign_r_buf); uint8_t *sign_s_buf = NULL; size_t sign_s_buf_sz = 0; hexstr_to_bytes(sign_s->valuestring, &sign_s_buf, &sign_s_buf_sz); - memcpy(sign_ctx->sign_s, sign_s_buf, sign_s_buf_sz); + memcpy(sign_ctx->signature + sign_r_buf_sz, sign_s_buf, sign_s_buf_sz); free(sign_s_buf); cJSON_Delete(root); diff --git a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c index b1dbef45fe4..284e4c69501 100644 --- a/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c +++ b/components/esp_tee/test_apps/tee_test_fw/main/test_esp_tee_sec_stg.c @@ -8,10 +8,6 @@ #include "esp_log.h" #include "esp_heap_caps.h" #include "esp_partition.h" - -#include "mbedtls/ecp.h" -#include "mbedtls/ecdsa.h" -#include "mbedtls/sha256.h" #include "ecdsa/ecdsa_alt.h" #include "esp_tee.h" @@ -25,6 +21,7 @@ #include "nvs.h" #include "unity.h" #include "sdkconfig.h" +#include "ecdsa/ecdsa_alt.h" /* Note: negative value here so that assert message prints a grep-able error hex value (mbedTLS uses -N for error codes) */ @@ -52,33 +49,52 @@ int verify_ecdsa_sign(const uint8_t *digest, size_t len, const esp_tee_sec_stora TEST_ASSERT_NOT_NULL(sign); TEST_ASSERT_NOT_EQUAL(0, len); - mbedtls_mpi r, s; - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); + int err = ESP_FAIL; - mbedtls_ecdsa_context ecdsa_context; - mbedtls_ecdsa_init(&ecdsa_context); + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); - mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_SECP256R1; + size_t pub_key_len; + size_t signature_size; if (is_crv_p192) { - curve_id = MBEDTLS_ECP_DP_SECP192R1; + psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8); + pub_key_len = ECDSA_SECP192R1_KEY_LEN; + signature_size = ECDSA_SECP192R1_KEY_LEN * 2; + } else { + psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8); + pub_key_len = ECDSA_SECP256R1_KEY_LEN; + signature_size = ECDSA_SECP256R1_KEY_LEN * 2; } - TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), curve_id)); - size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P); + uint8_t pub_key[2 * pub_key_len + 1]; + pub_key[0] = 0x04; + memcpy(pub_key + 1, pubkey->pub_x, pub_key_len); + memcpy(pub_key + 1 + pub_key_len, pubkey->pub_y, pub_key_len); - TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&r, sign->sign_r, plen)); - TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&s, sign->sign_s, plen)); - TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen)); - TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen)); - TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1)); - TEST_ASSERT_MBEDTLS_OK(mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s)); + psa_status_t status = psa_import_key(&key_attributes, pub_key, sizeof(pub_key), &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to import ECDSA public key: %ld", status); + err = ESP_ERR_INVALID_ARG; + goto exit; + } - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - mbedtls_ecdsa_free(&ecdsa_context); + status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, signature_size); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to verify ECDSA signature: %ld", status); + err = ESP_ERR_INVALID_ARG; + goto exit; + } - return 0; + psa_destroy_key(key_id); + psa_reset_key_attributes(&key_attributes); + + err = ESP_OK; + +exit: + return err; } TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_storage]") @@ -90,7 +106,9 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora esp_fill_random(message, buf_sz); uint8_t msg_digest[SHA256_DIGEST_SZ]; - TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256(message, buf_sz, msg_digest, false)); + size_t msg_digest_len = 0; + psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, buf_sz, msg_digest, sizeof(msg_digest), &msg_digest_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); free(message); esp_tee_sec_storage_key_cfg_t key_cfg = { @@ -108,12 +126,12 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora TEST_ESP_OK(esp_tee_sec_storage_gen_key(&key_cfg)); esp_tee_sec_storage_ecdsa_sign_t sign = {}; - TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, sizeof(msg_digest), &sign)); + TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, msg_digest_len, &sign)); esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {}; TEST_ESP_OK(esp_tee_sec_storage_ecdsa_get_pubkey(&key_cfg, &pubkey)); - TEST_ESP_OK(verify_ecdsa_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign, false)); + TEST_ESP_OK(verify_ecdsa_sign(msg_digest, msg_digest_len, &pubkey, &sign, false)); TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id)); } @@ -129,7 +147,10 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp192r1)", "[sec_stora esp_fill_random(message, buf_sz); uint8_t msg_digest[SHA256_DIGEST_SZ]; - TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256(message, buf_sz, msg_digest, false)); + size_t msg_digest_len = 0; + psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, buf_sz, msg_digest, sizeof(msg_digest), &msg_digest_len); + (void)msg_digest_len; + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); free(message); esp_tee_sec_storage_key_cfg_t key_cfg = { @@ -222,7 +243,9 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys", TEST_ASSERT_NOT_NULL(message); esp_fill_random(message, SZ); uint8_t msg_digest[SHA256_DIGEST_SZ]; - TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256(message, SZ, msg_digest, false)); + size_t msg_digest_len = 0; + psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, SZ, msg_digest, sizeof(msg_digest), &msg_digest_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); free(message); const char *key_id = "key_id_misc"; @@ -483,18 +506,18 @@ static void test_ecdsa_sign(mbedtls_ecp_group_id gid) }; TEST_ASSERT_EQUAL(0, esp_ecdsa_tee_set_pk_context(&key_ctx, &conf)); - mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(key_ctx); + mbedtls_ecp_keypair *keypair = key_ctx.MBEDTLS_PRIVATE(pk_ctx); //mbedtls_pk_ec(key_ctx); mbedtls_mpi key_mpi = keypair->MBEDTLS_PRIVATE(d); TEST_ASSERT_MBEDTLS_OK(mbedtls_ecdsa_sign(&ecdsa_context.MBEDTLS_PRIVATE(grp), &r, &s, &key_mpi, sha, SHA256_DIGEST_SZ, NULL, NULL)); esp_tee_sec_storage_ecdsa_sign_t sign = {}; - TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&r, sign.sign_r, key_len)); - TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&s, sign.sign_s, key_len)); + TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&r, sign.signature, key_len)); + TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&s, sign.signature + key_len, key_len)); TEST_ESP_OK(verify_ecdsa_sign(sha, sizeof(sha), &pubkey, &sign, is_crv_p192)); - mbedtls_pk_free(&key_ctx); + esp_ecdsa_free_pk_context(&key_ctx); mbedtls_ecdsa_free(&ecdsa_context); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); diff --git a/components/esp_tee/test_apps/tee_test_fw/sdkconfig.defaults b/components/esp_tee/test_apps/tee_test_fw/sdkconfig.defaults index 161c206fc4a..4b67d45b713 100644 --- a/components/esp_tee/test_apps/tee_test_fw/sdkconfig.defaults +++ b/components/esp_tee/test_apps/tee_test_fw/sdkconfig.defaults @@ -11,3 +11,6 @@ CONFIG_SECURE_TEE_TEST_MODE=y # Setting partition table CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y CONFIG_PARTITION_TABLE_OFFSET=0xF000 + +# TEE IRAM size +CONFIG_SECURE_TEE_IRAM_SIZE=0xC400 diff --git a/components/esp_wifi/test_apps/wifi_connect/main/app_main.c b/components/esp_wifi/test_apps/wifi_connect/main/app_main.c index 3d14ad85dcb..a96613c4cce 100644 --- a/components/esp_wifi/test_apps/wifi_connect/main/app_main.c +++ b/components/esp_wifi/test_apps/wifi_connect/main/app_main.c @@ -13,7 +13,7 @@ #include "esp_heap_caps.h" // Some resources are lazy allocated in wifi and lwip -#define TEST_MEMORY_LEAK_THRESHOLD (-1536) +#define TEST_MEMORY_LEAK_THRESHOLD (-1596) static size_t before_free_8bit; static size_t before_free_32bit; diff --git a/components/esp_wifi/test_apps/wifi_nvs_config/main/app_main.c b/components/esp_wifi/test_apps/wifi_nvs_config/main/app_main.c index d28da639a0a..4f455aa8e4f 100644 --- a/components/esp_wifi/test_apps/wifi_nvs_config/main/app_main.c +++ b/components/esp_wifi/test_apps/wifi_nvs_config/main/app_main.c @@ -13,7 +13,10 @@ #include "esp_heap_caps.h" // Some resources are lazy allocated in wifi and lwip -#define TEST_MEMORY_LEAK_THRESHOLD (-1536) +// #define TEST_MEMORY_LEAK_THRESHOLD (-1546) +// With PSA Migration, there is an increase in memory usage. +// TODO: Check why this is happening and fix it. +#define TEST_MEMORY_LEAK_THRESHOLD (-1750) static size_t before_free_8bit; static size_t before_free_32bit; diff --git a/components/espcoredump/include_core_dump/esp_core_dump_types.h b/components/espcoredump/include_core_dump/esp_core_dump_types.h index 13b5c49bbd3..2fb6c2bf438 100644 --- a/components/espcoredump/include_core_dump/esp_core_dump_types.h +++ b/components/espcoredump/include_core_dump/esp_core_dump_types.h @@ -89,7 +89,8 @@ extern "C" { typedef uint32_t core_dump_crc_t; #if CONFIG_IDF_TARGET_ESP32 -#include "mbedtls/sha256.h" /* mbedtls_sha256_context */ +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#include "mbedtls/private/sha256.h" typedef mbedtls_sha256_context sha256_ctx_t; #else #include "hal/sha_types.h" /* SHA_CTX */ diff --git a/components/espcoredump/src/core_dump_sha.c b/components/espcoredump/src/core_dump_sha.c index e77fd44745c..fd41dfa7a78 100644 --- a/components/espcoredump/src/core_dump_sha.c +++ b/components/espcoredump/src/core_dump_sha.c @@ -27,10 +27,6 @@ static void core_dump_sha256_start(core_dump_sha_ctx_t *sha_ctx) static void core_dump_sha256_update(core_dump_sha_ctx_t *sha_ctx, const void *data, size_t data_len) { - // set software mode of SHA calculation -#if CONFIG_MBEDTLS_HARDWARE_SHA - sha_ctx->ctx.mode = ESP_MBEDTLS_SHA256_SOFTWARE; -#endif mbedtls_sha256_update(&sha_ctx->ctx, data, data_len); } diff --git a/components/hal/test_apps/crypto/main/aes/test_aes.c b/components/hal/test_apps/crypto/main/aes/test_aes.c index e8c16732547..9069d0f5d01 100644 --- a/components/hal/test_apps/crypto/main/aes/test_aes.c +++ b/components/hal/test_apps/crypto/main/aes/test_aes.c @@ -57,11 +57,13 @@ static void test_cbc_aes(size_t buffer_size, const uint8_t expected_cipher_end[3 TEST_ASSERT_EQUAL(0, esp_aes_crypt_cbc(&ctx, ESP_AES_ENCRYPT, buffer_size, nonce, plaintext, ciphertext)); TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + buffer_size - 32, 32); + // Decrypt memcpy(nonce, iv, 16); TEST_ASSERT_EQUAL(0, esp_aes_crypt_cbc(&ctx, ESP_AES_DECRYPT, buffer_size, nonce, ciphertext, decryptedtext)); TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, buffer_size); + esp_aes_free(&ctx); // Free dynamically allocated memory @@ -222,7 +224,7 @@ static void test_cfb128_aes(size_t buffer_size, const uint8_t expected_cipher_en heap_caps_free(decryptedtext); } -#if SOC_GCM_SUPPORTED +#if CONFIG_SOC_AES_SUPPORT_GCM #define CIPHER_ID_AES 2 static void test_gcm_aes(size_t length, const uint8_t expected_last_block[16], const uint8_t expected_tag[16]) { @@ -339,7 +341,7 @@ TEST(aes, cfb128_aes_256_long_dma_test) #endif -#if SOC_GCM_SUPPORTED +#if CONFIG_SOC_AES_SUPPORT_GCM TEST(aes, gcm_aes_dma_test) { size_t length = 16; @@ -390,12 +392,12 @@ TEST_GROUP_RUNNER(aes) RUN_TEST_CASE(aes, cfb8_aes_256_long_dma_test); RUN_TEST_CASE(aes, cfb128_aes_256_long_dma_test); #endif /* CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT */ -#if SOC_GCM_SUPPORTED +#if CONFIG_SOC_AES_SUPPORT_GCM RUN_TEST_CASE(aes, gcm_aes_dma_test); #if CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT RUN_TEST_CASE(aes, gcm_aes_long_dma_test); #endif /* CONFIG_CRYPTO_TESTAPP_USE_AES_INTERRUPT */ -#endif /* SOC_GCM_SUPPORTED */ +#endif /* CONFIG_SOC_AES_SUPPORT_GCM */ #endif /* SOC_AES_SUPPORT_DMA */ } diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_m.S b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_m.S index 1e96dcc1a24..c75e51db555 100644 --- a/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_m.S +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/cpu_intr/test_vectors_m.S @@ -252,7 +252,7 @@ _test_panic_handler: /* Executing the panic handler */ li t0, 0xDEADC0DE - csrr t0, mscratch + csrw mscratch, t0 mv a0, sp csrr a1, mcause li t0, VECTORS_MCAUSE_REASON_MASK diff --git a/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_peri_apm.c b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_peri_apm.c index 3baa6a135ff..7e178759483 100644 --- a/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_peri_apm.c +++ b/components/hal/test_apps/tee/components/pms_and_cpu_intr/src/pms/test_tee_peri_apm.c @@ -76,35 +76,29 @@ static const uint32_t test_peri_apm_lp_peri_reg[] = { BIT64(APM_TEE_LP_PERIPH_LP_PERI) | \ BIT64(APM_TEE_LP_PERIPH_LP_APM)) -IRAM_ATTR static uint32_t reg_read(uint32_t addr) +FORCE_INLINE_ATTR uint32_t reg_read(uint32_t addr) { - uint32_t val; - asm volatile ( - "li t0, 0x100\n" - "lw %0, 0(%1)\n" - "1:\n" - "nop\n" - "addi t0, t0, -1\n" - "bnez t0, 1b\n" - : "=r"(val) + uint32_t value; + __asm__ volatile ( + "lw %0, 0(%1)\n" + "fence\n" + "nop\nnop\nnop\nnop\n" + : "=r"(value) : "r"(addr) - : "t0", "memory" + : "memory" ); - return val; + return value; } -IRAM_ATTR static void reg_write(uint32_t addr, uint32_t value) +FORCE_INLINE_ATTR void reg_write(uint32_t addr, uint32_t value) { - asm volatile ( - "li t0, 0x100\n" - "sw %1, 0(%0)\n" - "1:\n" - "nop\n" - "addi t0, t0, -1\n" - "bnez t0, 1b\n" + __asm__ volatile ( + "sw %1, 0(%0)\n" + "fence\n" + "nop\nnop\nnop\nnop\n" : : "r"(addr), "r"(value) - : "t0", "memory" + : "memory" ); } diff --git a/components/hal/test_apps/tee/pytest_pms_and_cpu_intr.py b/components/hal/test_apps/tee/pytest_pms_and_cpu_intr.py index a24ec3c15d4..323d507a831 100644 --- a/components/hal/test_apps/tee/pytest_pms_and_cpu_intr.py +++ b/components/hal/test_apps/tee/pytest_pms_and_cpu_intr.py @@ -58,4 +58,4 @@ def test_tee_peri_apm(dut: IdfDut) -> None: indirect=['config', 'target'], ) def test_tee_interrupts(dut: IdfDut) -> None: - dut.run_all_single_board_cases() + dut.run_all_single_board_cases(group='CPU') diff --git a/components/idf_test/include/esp32s2/idf_performance_target.h b/components/idf_test/include/esp32s2/idf_performance_target.h index 0d2b6f0dd36..1ef64601a7b 100644 --- a/components/idf_test/include/esp32s2/idf_performance_target.h +++ b/components/idf_test/include/esp32s2/idf_performance_target.h @@ -16,7 +16,7 @@ #define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 900 #define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900 -#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 13500 +#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 15500 #define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 650000 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 36000 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 960000 diff --git a/components/idf_test/include/esp32s3/idf_performance_target.h b/components/idf_test/include/esp32s3/idf_performance_target.h index 3b2bbe3b42f..071f0db403b 100644 --- a/components/idf_test/include/esp32s3/idf_performance_target.h +++ b/components/idf_test/include/esp32s3/idf_performance_target.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 23000 #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 diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index bcda4d69ae9..f11b9a7b4da 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -28,7 +28,13 @@ if(NOT ${IDF_TARGET} STREQUAL "linux") endif() set(mbedtls_srcs "") -set(mbedtls_include_dirs "port/include" "mbedtls/include" "mbedtls/library") +set(mbedtls_include_dirs + "port/include" + "mbedtls/include" + "mbedtls/library" + "mbedtls/tf-psa-crypto/core" + "mbedtls/tf-psa-crypto/drivers/builtin/src/" + ) if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL) list(APPEND mbedtls_include_dirs "port/mbedtls_rom") @@ -39,12 +45,17 @@ 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}" REQUIRES "${requires}" ) +# Add MBEDTLS_MAJOR_VERSION definition to the component library +target_compile_definitions(${COMPONENT_LIB} INTERFACE MBEDTLS_MAJOR_VERSION=4) + # Determine the type of mbedtls component library if(mbedtls_srcs STREQUAL "") # For no sources in component library we must use "INTERFACE" @@ -130,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 @@ -137,6 +150,13 @@ if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL) include_directories("${COMPONENT_DIR}/port/mbedtls_rom") endif() +# Set TF_PSA_CRYPTO_CONFIG_FILE before processing subdirectories to prevent override +set( + TF_PSA_CRYPTO_USER_CONFIG_FILE "mbedtls/esp_config.h" + CACHE STRING "Path to the PSA Crypto configuration file" + FORCE +) + # Import mbedtls library targets add_subdirectory(mbedtls) @@ -146,29 +166,84 @@ list(REMOVE_ITEM src_tls net_sockets.c) set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls}) if(CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1) -get_target_property(src_tls mbedtls SOURCES) -list(REMOVE_ITEM src_tls ssl_ciphersuites.c ssl_cli.c ssl_tls.c) -set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls}) + get_target_property(src_tls mbedtls SOURCES) + list(REMOVE_ITEM src_tls ssl_ciphersuites.c ssl_cli.c ssl_tls.c) + set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls}) -get_target_property(src_crypto mbedcrypto SOURCES) -list(REMOVE_ITEM src_crypto cipher_wrap.c ecdsa.c ecp.c ecp_curves.c oid.c pk_wrap.c) -set_property(TARGET mbedcrypto PROPERTY SOURCES ${src_crypto}) + message(STATUS "Setting up mbedtls") -get_target_property(src_x509 mbedx509 SOURCES) -list(REMOVE_ITEM src_x509 x509_crt.c) -set_property(TARGET mbedx509 PROPERTY SOURCES ${src_x509}) + # list(REMOVE_ITEM src_crypto sha512.c) + # list(REMOVE_ITEM src_crypto cipher_wrap.c ecdsa.c ecp.c ecp_curves.c oid.c pk_wrap.c) + # set_property(TARGET tfpsacrypto PROPERTY SOURCES ${src_crypto}) + + get_target_property(src_builtin builtin SOURCES) + message(STATUS "src_builtin: ${src_builtin}") + + get_target_property(src_x509 mbedx509 SOURCES) + list(REMOVE_ITEM src_x509 x509_crt.c) + set_property(TARGET mbedx509 PROPERTY SOURCES ${src_x509}) endif() # Core libraries from the mbedTLS project -set(mbedtls_targets mbedtls mbedcrypto mbedx509) +set(mbedtls_targets mbedtls mbedx509 tfpsacrypto builtin) + +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) + target_include_directories(tfpsacrypto PUBLIC "${COMPONENT_DIR}/port/psa_driver/include") +endif() + +message(STATUS "Setting up mbedtls configuration") +foreach(target ${mbedtls_targets}) + target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h") + set_config_files_compile_definitions(${target}) + target_compile_definitions(${target} PUBLIC MBEDTLS_MAJOR_VERSION=4) + if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10087 + target_compile_options(${target} PRIVATE "-fno-analyzer") + endif() + if(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_SIZE) + target_compile_options(${target} PRIVATE "-Os") + elseif(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_PERF) + target_compile_options(${target} PRIVATE "-O2") + endif() +endforeach() + # 3rd party libraries from the mbedTLS project list(APPEND mbedtls_targets everest p256m) set(mbedtls_target_sources "${COMPONENT_DIR}/port/mbedtls_debug.c" "${COMPONENT_DIR}/port/esp_platform_time.c") +if(CONFIG_MBEDTLS_VER_4_X_SUPPORT) + list(APPEND mbedtls_target_sources "${COMPONENT_DIR}/port/esp_psa_crypto_init.c") + # Add ESP-IDF NVS-based PSA ITS implementation + # Only compile esp_psa_its.c if nvs_flash component is available + if(NOT ${IDF_TARGET} STREQUAL "linux") + if(IDF_BUILD_V2) + # For v2: conditionally compile source and link only if nvs_flash target exists + target_sources( + tfpsacrypto PRIVATE + "$<$:${COMPONENT_DIR}/port/psa_crypto_storage/esp_psa_its.c>" + ) + target_link_libraries(tfpsacrypto PRIVATE "$<$:idf::nvs_flash>") + # Define compile definition to indicate ESP-IDF PSA ITS implementation is available + target_compile_definitions(tfpsacrypto PRIVATE "$<$:ESP_PSA_ITS_AVAILABLE>") + else() + # For v1: check if component is in build before adding source and linking + idf_build_get_property(build_components BUILD_COMPONENTS) + if(nvs_flash IN_LIST build_components) + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/psa_crypto_storage/esp_psa_its.c") + idf_component_get_property(nvs_flash_lib nvs_flash COMPONENT_LIB) + target_link_libraries(tfpsacrypto PRIVATE ${nvs_flash_lib}) + target_compile_definitions(tfpsacrypto PRIVATE ESP_PSA_ITS_AVAILABLE) + endif() + endif() + endif() +endif() + if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) -set(mbedtls_target_sources ${mbedtls_target_sources} + set(mbedtls_target_sources ${mbedtls_target_sources} "${COMPONENT_DIR}/port/dynamic/esp_mbedtls_dynamic_impl.c" "${COMPONENT_DIR}/port/dynamic/esp_ssl_cli.c" "${COMPONENT_DIR}/port/dynamic/esp_ssl_srv.c" @@ -176,13 +251,13 @@ set(mbedtls_target_sources ${mbedtls_target_sources} endif() if(${IDF_TARGET} STREQUAL "linux") -set(mbedtls_target_sources ${mbedtls_target_sources} "${COMPONENT_DIR}/port/net_sockets.c") + set(mbedtls_target_sources ${mbedtls_target_sources} "${COMPONENT_DIR}/port/net_sockets.c") endif() # While updating to MbedTLS release/v3.4.0, building mbedtls/library/psa_crypto.c # clang produces an unreachable-code warning. if(CMAKE_C_COMPILER_ID MATCHES "Clang") - target_compile_options(mbedcrypto PRIVATE "-Wno-unreachable-code") + target_compile_options(tfpsacrypto PRIVATE "-Wno-unreachable-code") endif() # net_sockets.c should only be compiled if BSD socket functions are available. @@ -202,7 +277,8 @@ endif() target_sources(mbedtls PRIVATE ${mbedtls_target_sources}) if(NOT ${IDF_TARGET} STREQUAL "linux") - target_link_libraries(mbedcrypto PRIVATE idf::esp_security) + target_link_libraries(tfpsacrypto PRIVATE idf::esp_security) + target_link_libraries(builtin PRIVATE idf::esp_security) endif() # Choose peripheral type @@ -215,18 +291,25 @@ if(CONFIG_SOC_SHA_SUPPORTED) endif() endif() -if(SHA_PERIPHERAL_TYPE STREQUAL "core") - target_include_directories(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/core/include") +if(CONFIG_SOC_AES_SUPPORTED) + if(CONFIG_SOC_AES_SUPPORT_DMA) + set(AES_PERIPHERAL_TYPE "dma") + else() + set(AES_PERIPHERAL_TYPE "block") + endif() +endif() +if(SHA_PERIPHERAL_TYPE STREQUAL "core") + 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(mbedcrypto PRIVATE "${SHA_CORE_SRCS}") + target_sources(tfpsacrypto PRIVATE "${SHA_CORE_SRCS}") endif() -if(CONFIG_SOC_AES_SUPPORT_DMA) +if(AES_PERIPHERAL_TYPE STREQUAL "dma") if(NOT CONFIG_SOC_AES_GDMA) set(AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_crypto_dma_impl.c") else() @@ -235,47 +318,66 @@ if(CONFIG_SOC_AES_SUPPORT_DMA) list(APPEND AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c") - target_include_directories(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/dma/include") - target_sources(mbedcrypto PRIVATE "${AES_DMA_SRCS}") + target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/aes/dma/include") + target_sources(tfpsacrypto PRIVATE "${AES_DMA_SRCS}") endif() -if((SHA_PERIPHERAL_TYPE STREQUAL "core" AND CONFIG_SOC_SHA_SUPPORT_DMA) OR CONFIG_SOC_AES_SUPPORT_DMA) - target_link_libraries(mbedcrypto PRIVATE idf::esp_mm) +if((SHA_PERIPHERAL_TYPE STREQUAL "core" AND CONFIG_SOC_SHA_SUPPORT_DMA) OR AES_PERIPHERAL_TYPE STREQUAL "dma") + target_link_libraries(tfpsacrypto PRIVATE idf::esp_mm) + target_link_libraries(builtin PRIVATE idf::esp_mm) if(CONFIG_SOC_SHA_GDMA OR CONFIG_SOC_AES_GDMA) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/crypto_shared_gdma/esp_crypto_shared_gdma.c") + if(CONFIG_SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT) + target_link_libraries(tfpsacrypto PRIVATE idf::bootloader_support) + target_link_libraries(builtin PRIVATE idf::bootloader_support) + endif() + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/crypto_shared_gdma/esp_crypto_shared_gdma.c") endif() endif() if(NOT ${IDF_TARGET} STREQUAL "linux") - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c") + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c") endif() -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_mem.c" - "${COMPONENT_DIR}/port/esp_timing.c" +target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_mem.c" + # "${COMPONENT_DIR}/port/esp_timing.c" ) if(CONFIG_SOC_AES_SUPPORTED) - target_include_directories(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/include") - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_xts.c" + target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/aes/include") + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_xts.c" "${COMPONENT_DIR}/port/aes/esp_aes_common.c" "${COMPONENT_DIR}/port/aes/esp_aes.c" ) endif() if(CONFIG_SOC_SHA_SUPPORTED) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/esp_sha.c" - "${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_sha256.c" + "${COMPONENT_DIR}/port/psa_driver/esp_sha/${SHA_PERIPHERAL_TYPE}/psa_crypto_driver_esp_sha512.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) -target_sources(mbedcrypto PRIVATE +target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c" "${COMPONENT_DIR}/port/esp_ds/esp_rsa_dec_alt.c" "${COMPONENT_DIR}/port/esp_ds/esp_ds_common.c") endif() +# # CONFIG_ESP_TLS_USE_DS_PERIPHERAL can be enabled only for the supported targets. +if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c") +endif() if(CONFIG_SOC_HMAC_SUPPORTED) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c") + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c") endif() # Note: some mbedTLS hardware acceleration can be enabled/disabled by config. @@ -286,28 +388,36 @@ endif() # The other port-specific files don't override internal mbedTLS functions, they just add new functions. if(CONFIG_MBEDTLS_HARDWARE_MPI) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/bignum/esp_bignum.c" + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/bignum/esp_bignum.c" "${COMPONENT_DIR}/port/bignum/bignum_alt.c") endif() -if(CONFIG_MBEDTLS_HARDWARE_SHA) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha1.c" - "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha256.c" - "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha512.c" - ) -endif() - if(CONFIG_MBEDTLS_HARDWARE_GCM OR CONFIG_MBEDTLS_HARDWARE_AES) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c") + target_compile_definitions(tfpsacrypto PRIVATE ESP_AES_DRIVER_ENABLED) + target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/include/aes") + target_sources(tfpsacrypto PRIVATE + "${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c" + ) + if(CONFIG_MBEDTLS_HARDWARE_SHA) + target_sources(tfpsacrypto PRIVATE + "${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c" + ) + endif() + if(CONFIG_SOC_AES_SUPPORT_GCM) + target_sources(tfpsacrypto PRIVATE "$ENV{IDF_PATH}/components/mbedtls/port/aes/esp_aes_gcm.c" + "${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c") + endif() endif() if(CONFIG_MBEDTLS_HARDWARE_ECC) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecc/esp_ecc.c" + target_sources(builtin PRIVATE "${COMPONENT_DIR}/port/ecc/esp_ecc.c" "${COMPONENT_DIR}/port/ecc/ecc_alt.c") + include_directories("${COMPONENT_DIR}/tf-psa-crypto/drivers/builtin/include/mbedtls") endif() -if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY OR CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecdsa/ecdsa_alt.c") +if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR +CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY OR CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN) + target_sources(builtin PRIVATE "${COMPONENT_DIR}/port/ecdsa/ecdsa_alt.c") set(WRAP_FUNCTIONS_SIGN mbedtls_ecdsa_sign @@ -339,35 +449,37 @@ if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY OR endif() if(CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN) - target_link_libraries(mbedcrypto PRIVATE idf::tee_sec_storage) + target_link_libraries(builtin PRIVATE idf::tee_sec_storage) endif() endif() -if(CONFIG_MBEDTLS_ROM_MD5) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/md/esp_md.c") +# if(CONFIG_MBEDTLS_ROM_MD5) +# target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/md/esp_md.c") +# endif() + +# if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL) +# target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/mbedtls_rom/mbedtls_rom_osi.c") +# target_link_libraries(${COMPONENT_LIB} PRIVATE "-u mbedtls_rom_osi_functions_init") +# endif() + +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-analyzer") + target_compile_options(tfpsacrypto PRIVATE "-fno-analyzer") endif() -if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/mbedtls_rom/mbedtls_rom_osi.c") - target_link_libraries(${COMPONENT_LIB} PRIVATE "-u mbedtls_rom_osi_functions_init") +# If linkage_type is PUBLIC, use PRIVATE while setting compiler optimization flags +# as we don't want the optimization flags to modify other targets +if(linkage_type STREQUAL "PUBLIC") + set(compiler_linkage_type PRIVATE) +else() + set(compiler_linkage_type ${linkage_type}) endif() -foreach(target ${mbedtls_targets}) - target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h") - if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10087 - target_compile_options(${target} PRIVATE "-fno-analyzer") - endif() - if(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_SIZE) - target_compile_options(${target} PRIVATE "-Os") - elseif(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_SPEED) - target_compile_options(${target} PRIVATE "-O2") - endif() -endforeach() - if(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_SIZE) - target_compile_options(${COMPONENT_LIB} PRIVATE "-Os") -elseif(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_SPEED) - target_compile_options(${COMPONENT_LIB} PRIVATE "-O2") + message(STATUS "Linkage type is ${linkage_type}") + target_compile_options(${COMPONENT_LIB} ${compiler_linkage_type} "-Os") +elseif(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_PERF) + target_compile_options(${COMPONENT_LIB} ${compiler_linkage_type} "-O2") endif() if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) @@ -388,37 +500,121 @@ if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) endforeach() endif() -set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_LIBRARIES mbedtls) +# set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_LIBRARIES mbedtls) if(CONFIG_PM_ENABLE) - target_link_libraries(mbedcrypto PRIVATE idf::esp_pm) + target_link_libraries(tfpsacrypto PRIVATE idf::esp_pm) endif() if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY) - target_link_libraries(mbedcrypto PRIVATE idf::efuse) + target_link_libraries(builtin PRIVATE idf::efuse) endif() target_link_libraries(${COMPONENT_LIB} ${linkage_type} ${mbedtls_targets}) -if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL) - # The linker seems to be unable to resolve all the dependencies without increasing this - set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 6) +# Ensure PSA crypto initialization is included in the build +if(NOT ${IDF_TARGET} STREQUAL "linux") + target_link_libraries(${COMPONENT_LIB} ${linkage_type} "-u mbedtls_psa_crypto_init_include_impl") endif() # Additional optional dependencies for the mbedcrypto library -function(mbedcrypto_optional_deps component_name) +function(builtin_optional_deps component_name) idf_build_get_property(components BUILD_COMPONENTS) if(${component_name} IN_LIST components) idf_component_get_property(lib_name ${component_name} COMPONENT_LIB) - target_link_libraries(mbedcrypto PRIVATE ${lib_name}) + target_link_libraries(builtin PRIVATE ${lib_name}) endif() endfunction() if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM) - mbedcrypto_optional_deps(esp_timer idf::esp_timer) + builtin_optional_deps(esp_timer idf::esp_timer) endif() -# Link esp-cryptoauthlib to mbedtls -if(CONFIG_ATCA_MBEDTLS_ECDSA) - mbedcrypto_optional_deps(espressif__esp-cryptoauthlib esp-cryptoauthlib) +# # Link esp-cryptoauthlib to mbedtls +# if(CONFIG_ATCA_MBEDTLS_ECDSA) +# mbedcrypto_optional_deps(espressif__esp-cryptoauthlib esp-cryptoauthlib) +# endif() + +# Apply -fno-analyzer to ALL mbedTLS targets at the very end when all targets are created +if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") + message(STATUS "Applying -fno-analyzer to all mbedTLS targets...") + + # Get all targets from all directories + get_property( + all_mbedtls_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/mbedtls PROPERTY BUILDSYSTEM_TARGETS + ) + get_property( + drivers_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/mbedtls/tf-psa-crypto/drivers PROPERTY BUILDSYSTEM_TARGETS + ) + + message(STATUS "Found mbedtls targets: ${all_mbedtls_targets}") + message(STATUS "Found drivers targets: ${drivers_targets}") + + # Get targets from nested driver subdirectories + foreach(subdir IN ITEMS builtin everest p256-m) + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/mbedtls/tf-psa-crypto/drivers/${subdir}) + get_property( + subdir_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/mbedtls/tf-psa-crypto/drivers/${subdir} + PROPERTY BUILDSYSTEM_TARGETS + ) + message(STATUS "Found ${subdir} targets: ${subdir_targets}") + list(APPEND drivers_targets ${subdir_targets}) + endif() + endforeach() + + # Combine all target lists + set(all_targets ${all_mbedtls_targets} ${drivers_targets}) + message(STATUS "All combined targets: ${all_targets}") + + # Apply -fno-analyzer to each target + foreach(target ${all_targets}) + if(TARGET ${target}) + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL "STATIC_LIBRARY" OR + target_type STREQUAL "SHARED_LIBRARY" OR + target_type STREQUAL "MODULE_LIBRARY" OR + target_type STREQUAL "OBJECT_LIBRARY" OR + target_type STREQUAL "EXECUTABLE") + message(STATUS "Applying -fno-analyzer to target: ${target}") + target_compile_options(${target} PRIVATE "-fno-analyzer") + endif() + endif() + endforeach() + + # Also check for any targets that might have been missed by using global target list + get_property(global_targets GLOBAL PROPERTY TARGETS) + set(mbedtls_global_targets "") + foreach(target ${global_targets}) + if(TARGET ${target}) + get_target_property(target_source_dir ${target} SOURCE_DIR) + if(target_source_dir) + # Check if target is from mbedtls directory or has mbedtls-related names + string(FIND "${target_source_dir}" "mbedtls" pos) + string(FIND "${target}" "mbedtls" name_pos) + string(FIND "${target}" "tfpsacrypto" tfpsa_pos) + # string(FIND "${target}" "everest" everest_pos) + # string(FIND "${target}" "p256m" p256m_pos) + string(FIND "${target}" "builtin" builtin_pos) + if(pos GREATER -1 OR name_pos GREATER -1 OR tfpsa_pos GREATER -1 OR builtin_pos GREATER -1) + list(APPEND mbedtls_global_targets ${target}) + get_target_property(target_type ${target} TYPE) + # Skip ALIAS targets as they don't have compile options + if(NOT target_type STREQUAL "ALIAS" AND + (target_type STREQUAL "STATIC_LIBRARY" OR + target_type STREQUAL "SHARED_LIBRARY" OR + target_type STREQUAL "MODULE_LIBRARY" OR + target_type STREQUAL "OBJECT_LIBRARY" OR + target_type STREQUAL "EXECUTABLE")) + # Check if -fno-analyzer was already applied + get_target_property(compile_options ${target} COMPILE_OPTIONS) + if(NOT compile_options OR NOT "-fno-analyzer" IN_LIST compile_options) + message(STATUS "Applying -fno-analyzer to missed target: ${target}") + target_compile_options(${target} PRIVATE "-fno-analyzer") + endif() + endif() + endif() + endif() + endif() + endforeach() + message(STATUS "All mbedtls-related global targets: ${mbedtls_global_targets}") endif() diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 28295bf7e28..0ea2c255693 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -1,9 +1,14 @@ menu "mbedTLS" menu "Core Configuration" + + config MBEDTLS_VER_4_X_SUPPORT + bool + default y + choice MBEDTLS_COMPILER_OPTIMIZATION prompt "Compiler optimization level" - default MBEDTLS_COMPILER_OPTIMIZATION_NONE + default MBEDTLS_COMPILER_OPTIMIZATION_SIZE help This option allows you to select the compiler optimization level for mbedTLS. The default is set to the optimization level used by the rest of the ESP-IDF project. @@ -345,14 +350,14 @@ menu "mbedTLS" config MBEDTLS_PK_PARSE_C bool "Enables generic public key parsing functions" default y - depends on MBEDTLS_ASN1_PARSE_C && MBEDTLS_PK_C && MBEDTLS_OID_C + depends on MBEDTLS_ASN1_PARSE_C && MBEDTLS_PK_C help Enable generic public key parsing functions. config MBEDTLS_PK_WRITE_C bool "Enables generic public key writing functions" default y - depends on MBEDTLS_PK_C && MBEDTLS_OID_C && MBEDTLS_ASN1_WRITE_C + depends on MBEDTLS_PK_C && MBEDTLS_ASN1_WRITE_C help Enable generic public key writing functions. @@ -387,7 +392,7 @@ menu "mbedTLS" config MBEDTLS_X509_CREATE_C bool "X.509 certificate creation" default n - depends on MBEDTLS_BIGNUM_C && MBEDTLS_OID_C && \ + depends on MBEDTLS_BIGNUM_C && \ MBEDTLS_PK_WRITE_C && MBEDTLS_MD_C help Support for creating X.509 certificates and CSRs. @@ -435,13 +440,6 @@ menu "mbedTLS" help Enable ASN.1 writing functions. - config MBEDTLS_OID_C - bool "Enable OID support" - default y - help - Enable support for Object Identifier (OID) parsing and printing. - This is used by X.509 and PKCS#11. - config MBEDTLS_CERTIFICATE_BUNDLE bool "Enable trusted root certificate bundle" default y @@ -526,7 +524,6 @@ menu "mbedTLS" config MBEDTLS_TLS_ENABLED bool "Enable TLS protocol support" default y - select MBEDTLS_CIPHER_C select MBEDTLS_SHA256_C select MBEDTLS_MD_C select MBEDTLS_SSL_PROTO_TLS1_2 @@ -547,7 +544,6 @@ menu "mbedTLS" config MBEDTLS_SSL_PROTO_TLS1_3 bool "Support TLS 1.3 protocol" depends on MBEDTLS_TLS_ENABLED - select MBEDTLS_HKDF_C select MBEDTLS_SSL_KEEP_PEER_CERTIFICATE default n @@ -690,13 +686,6 @@ menu "mbedTLS" help Enable to support symmetric key PSK (pre-shared-key) TLS key exchange modes. - config MBEDTLS_KEY_EXCHANGE_DHE_PSK - bool "Enable DHE-PSK based ciphersuite modes" - depends on MBEDTLS_PSK_MODES && MBEDTLS_DHM_C - default y - help - Enable to support Diffie-Hellman PSK (pre-shared-key) TLS authentication modes. - config MBEDTLS_KEY_EXCHANGE_ECDHE_PSK bool "Enable ECDHE-PSK based ciphersuite modes" depends on MBEDTLS_PSK_MODES && MBEDTLS_ECDH_C @@ -707,7 +696,7 @@ menu "mbedTLS" config MBEDTLS_KEY_EXCHANGE_RSA_PSK bool "Enable RSA-PSK based ciphersuite modes" depends on MBEDTLS_PSK_MODES - default y + default n help Enable to support RSA PSK (pre-shared-key) TLS authentication modes. @@ -717,13 +706,6 @@ menu "mbedTLS" help Enable to support ciphersuites with prefix TLS-RSA-WITH- - config MBEDTLS_KEY_EXCHANGE_DHE_RSA - bool "Enable DHE-RSA based ciphersuite modes" - default y - depends on MBEDTLS_DHM_C - help - Enable to support ciphersuites with prefix TLS-DHE-RSA-WITH- - config MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE bool "Support Elliptic Curve based ciphersuites" depends on MBEDTLS_ECP_C @@ -748,20 +730,6 @@ menu "mbedTLS" help Enable to support ciphersuites with prefix TLS-ECDHE-ECDSA-WITH- - config MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA - bool "Enable ECDH-ECDSA based ciphersuite modes" - depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C && MBEDTLS_ECDSA_C - default y - help - Enable to support ciphersuites with prefix TLS-ECDH-ECDSA-WITH- - - config MBEDTLS_KEY_EXCHANGE_ECDH_RSA - bool "Enable ECDH-RSA based ciphersuite modes" - depends on MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE && MBEDTLS_ECDH_C - default y - help - Enable to support ciphersuites with prefix TLS-ECDH-RSA-WITH- - config MBEDTLS_KEY_EXCHANGE_ECJPAKE bool "Enable ECJPAKE based ciphersuite modes" depends on MBEDTLS_ECJPAKE_C && MBEDTLS_ECP_DP_SECP256R1_ENABLED @@ -889,15 +857,6 @@ menu "mbedTLS" Disabling this option will save some code size. endmenu - config MBEDTLS_CIPHER_C - bool "Cipher abstraction layer" - default y - help - Enable the cipher abstraction layer. This enables generic cipher wrappers - for the block ciphers and stream ciphers. - If you are not using the cipher abstraction layer, you can disable this - option to save some code size. - menu "Symmetric Ciphers" config MBEDTLS_AES_C bool "AES block cipher" @@ -991,7 +950,7 @@ menu "mbedTLS" config MBEDTLS_GCM_C bool "GCM (Galois/Counter) block cipher modes" default y - depends on (MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C) && MBEDTLS_CIPHER_C + depends on (MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C) help Enable Galois/Counter Mode for AES and/or Camellia ciphers. @@ -1000,53 +959,10 @@ menu "mbedTLS" config MBEDTLS_NIST_KW_C bool "NIST key wrapping (KW) and KW padding (KWP)" default n - depends on MBEDTLS_AES_C && MBEDTLS_CIPHER_C + depends on MBEDTLS_AES_C help Enable NIST key wrapping and key wrapping padding. - config MBEDTLS_CIPHER_PADDING - bool "Cipher padding" - default y - depends on MBEDTLS_CIPHER_MODE_CBC || MBEDTLS_CIPHER_MODE_CFB || MBEDTLS_CIPHER_MODE_OFB - help - Enable padding for block ciphers. - - Padding is only used for block ciphers in CBC, CFB, CTR and OFB modes. - If you are using a stream cipher or a block cipher in ECB mode, you can - disable this option to save code size. - - config MBEDTLS_CIPHER_PADDING_PKCS7 - bool "PKCS#7 padding" - default y - depends on MBEDTLS_CIPHER_PADDING && \ - (MBEDTLS_CIPHER_MODE_CBC || MBEDTLS_CIPHER_MODE_CFB || MBEDTLS_CIPHER_MODE_OFB) - help - Enable PKCS#7 padding for block ciphers. - - config MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS - bool "One and zeros padding" - default y - depends on MBEDTLS_CIPHER_PADDING && \ - (MBEDTLS_CIPHER_MODE_CBC || MBEDTLS_CIPHER_MODE_CFB || MBEDTLS_CIPHER_MODE_OFB) - help - Enable one and zeros padding for block ciphers. - - config MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN - bool "Zeros and length padding" - default y - depends on MBEDTLS_CIPHER_PADDING && \ - (MBEDTLS_CIPHER_MODE_CBC || MBEDTLS_CIPHER_MODE_CFB || MBEDTLS_CIPHER_MODE_OFB) - help - Enable zeros and length padding for block ciphers. - - config MBEDTLS_CIPHER_PADDING_ZEROS - bool "Zeros padding" - default y - depends on MBEDTLS_CIPHER_PADDING && \ - (MBEDTLS_CIPHER_MODE_CBC || MBEDTLS_CIPHER_MODE_CFB || MBEDTLS_CIPHER_MODE_OFB) - help - Enable zeros padding for block ciphers. - config MBEDTLS_AES_ROM_TABLES bool "Store AES tables in ROM" default y @@ -1074,7 +990,6 @@ menu "mbedTLS" config MBEDTLS_CMAC_C bool "Enable CMAC mode for block ciphers" default y - select MBEDTLS_CIPHER_C depends on (MBEDTLS_AES_C || MBEDTLS_DES_C) help Enable the CMAC (Cipher-based Message Authentication Code) mode for @@ -1093,18 +1008,10 @@ menu "mbedTLS" If you don't need any of these algorithms, you can disable this option to save code size. - config MBEDTLS_GENPRIME - bool "Enable hardware prime number generation" - default y - depends on MBEDTLS_BIGNUM_C - help - Enable prime number generation. - config MBEDTLS_RSA_C bool "RSA public key cryptosystem" default y select MBEDTLS_BIGNUM_C - select MBEDTLS_OID_C help Enable RSA. Needed to use RSA-xxx TLS ciphersuites. @@ -1112,20 +1019,6 @@ menu "mbedTLS" bool "Enable Elliptic Curve Ciphers(ECC) support" default y menu "Supported Curves" - config MBEDTLS_ECP_DP_SECP192R1_ENABLED - bool "Enable SECP192R1 curve" - depends on MBEDTLS_ECP_C - default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) - help - Enable support for SECP192R1 Elliptic Curve. - - config MBEDTLS_ECP_DP_SECP224R1_ENABLED - bool "Enable SECP224R1 curve" - depends on MBEDTLS_ECP_C - default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) - help - Enable support for SECP224R1 Elliptic Curve. - config MBEDTLS_ECP_DP_SECP256R1_ENABLED bool "Enable SECP256R1 curve" depends on MBEDTLS_ECP_C @@ -1147,20 +1040,6 @@ menu "mbedTLS" help Enable support for SECP521R1 Elliptic Curve. - config MBEDTLS_ECP_DP_SECP192K1_ENABLED - bool "Enable SECP192K1 curve" - depends on MBEDTLS_ECP_C - default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) - help - Enable support for SECP192K1 Elliptic Curve. - - config MBEDTLS_ECP_DP_SECP224K1_ENABLED - bool "Enable SECP224K1 curve" - depends on MBEDTLS_ECP_C - default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) - help - Enable support for SECP224K1 Elliptic Curve. - config MBEDTLS_ECP_DP_SECP256K1_ENABLED bool "Enable SECP256K1 curve" depends on MBEDTLS_ECP_C @@ -1227,9 +1106,10 @@ menu "mbedTLS" Define this option only if you enable MBEDTLS_ECP_RESTARTABLE or if you want to access ECDH context fields directly. + # TODO: IDF-15031 config MBEDTLS_DHM_C bool "Diffie-Hellman-Merkle key exchange (DHM)" - default y + default n select MBEDTLS_BIGNUM_C depends on MBEDTLS_ECP_C help @@ -1298,14 +1178,6 @@ menu "mbedTLS" endmenu menu "Hash functions" - config MBEDTLS_HKDF_C - bool "HKDF algorithm (RFC 5869)" - default n - depends on MBEDTLS_MD_C - help - Enable support for the Hashed Message Authentication Code - (HMAC)-based key derivation function (HKDF). - config MBEDTLS_POLY1305_C bool "Poly1305 MAC algorithm" default n @@ -1517,7 +1389,7 @@ menu "mbedTLS" bool "Fallback to software implementation for larger MPI values" depends on MBEDTLS_HARDWARE_MPI default y if SOC_RSA_MAX_BIT_LEN <= 3072 # HW max 3072 bits - default n + default y help Fallback to software implementation for RSA key lengths larger than SOC_RSA_MAX_BIT_LEN. If this is not active @@ -1662,12 +1534,6 @@ menu "mbedTLS" it also increases the binary size by ~1.2 KB as it pulls in the peripheral's block mode code as well. - config MBEDTLS_PK_RSA_ALT_SUPPORT - bool "Enable RSA alt support" - default y - help - Support external private RSA keys (eg from a HSM) int the PK layer. - config MBEDTLS_ATCA_HW_ECDSA_SIGN bool "Enable hardware ECDSA sign acceleration when using ATECC608A" default n @@ -1684,14 +1550,6 @@ menu "mbedTLS" endmenu menu "Entropy and Random Number Generation" - config MBEDTLS_ENTROPY_C - bool "Enable entropy support" - default y - depends on MBEDTLS_SHA256_C || MBEDTLS_SHA512_C - help - Enable support for entropy sources and provides a generic - entropy pool. - config MBEDTLS_ENTROPY_FORCE_SHA256 bool "Force SHA-256 for entropy" default n @@ -1733,17 +1591,11 @@ menu "mbedTLS" config MBEDTLS_PKCS7_C bool "Enable PKCS number 7" default y - depends on MBEDTLS_ASN1_PARSE_C && MBEDTLS_OID_C && MBEDTLS_PK_PARSE_C && \ + depends on MBEDTLS_ASN1_PARSE_C && MBEDTLS_PK_PARSE_C && \ MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_X509_CRL_PARSE_C && MBEDTLS_BIGNUM_C && MBEDTLS_MD_C help Enable PKCS number 7 core for using PKCS number 7-formatted signatures. - config MBEDTLS_PKCS12_C - bool "Enable PKCS number 12" - default y - depends on MBEDTLS_ASN1_PARSE_C && (MBEDTLS_MD_C) - help - Enable PKCS number 12 core for using PKCS number 12-formatted signatures. config MBEDTLS_PKCS1_V15 bool "Enable PKCS#1 v1.5 padding" default y @@ -1776,7 +1628,8 @@ menu "mbedTLS" config MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER bool "Use ROM implementation of the crypto algorithm in the bootloader" - depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB + # TODO: IDF-15012 + depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB && !MBEDTLS_VER_4_X_SUPPORT default "n" select MBEDTLS_AES_C help @@ -1787,7 +1640,8 @@ menu "mbedTLS" config MBEDTLS_USE_CRYPTO_ROM_IMPL bool "Use ROM implementation of the crypto algorithm" - depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB + # TODO: IDF-15012 + depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB && !MBEDTLS_VER_4_X_SUPPORT default "n" select MBEDTLS_SHA512_C select MBEDTLS_AES_C diff --git a/components/mbedtls/config/mbedtls_preset_bt.conf b/components/mbedtls/config/mbedtls_preset_bt.conf index 8a816c6f087..93b9f68aa6b 100644 --- a/components/mbedtls/config/mbedtls_preset_bt.conf +++ b/components/mbedtls/config/mbedtls_preset_bt.conf @@ -31,7 +31,6 @@ CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=n CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=n # TLS Key Exchange Configuration -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=n CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=n CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=n CONFIG_MBEDTLS_SSL_ALPN=n @@ -39,11 +38,6 @@ CONFIG_MBEDTLS_SSL_RENEGOTIATION=n CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=n CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=n -# DTLS Protocol Configuration - -# Cipher Abstraction Layer -CONFIG_MBEDTLS_CIPHER_C=y - # Symmetric Ciphers CONFIG_MBEDTLS_ARIA_C=n CONFIG_MBEDTLS_CCM_C=n @@ -54,23 +48,15 @@ CONFIG_MBEDTLS_CIPHER_MODE_OFB=n CONFIG_MBEDTLS_CIPHER_MODE_XTS=y CONFIG_MBEDTLS_GCM_C=n CONFIG_MBEDTLS_PKCS5_C=n -CONFIG_MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS=n -CONFIG_MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN=n -CONFIG_MBEDTLS_CIPHER_PADDING_ZEROS=n CONFIG_MBEDTLS_AES_FEWER_TABLES=y # Elliptic Curve Ciphers Configuration -CONFIG_MBEDTLS_ECP_NIST_OPTIM=n -CONFIG_MBEDTLS_DHM_C=n +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y CONFIG_MBEDTLS_ECDSA_C=y CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=n CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=n -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=n -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=n -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=n -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=n @@ -84,12 +70,10 @@ CONFIG_MBEDTLS_SHA512_C=n CONFIG_MBEDTLS_MD5_C=n CONFIG_MBEDTLS_MPI_USE_INTERRUPT=n CONFIG_MBEDTLS_ECC_OTHER_CURVES_SOFT_FALLBACK=n -CONFIG_MBEDTLS_GENPRIME=y -CONFIG_MBEDTLS_PKCS12_C=n CONFIG_MBEDTLS_PKCS1_V21=n -CONFIG_MBEDTLS_ENTROPY_FORCE_SHA256=y +CONFIG_MBEDTLS_ENTROPY_FORCE_SHA256=n CONFIG_MBEDTLS_CTR_DRBG_C=y CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=n diff --git a/components/mbedtls/config/mbedtls_preset_default.conf b/components/mbedtls/config/mbedtls_preset_default.conf index f34bd4d963a..affbd1556ef 100644 --- a/components/mbedtls/config/mbedtls_preset_default.conf +++ b/components/mbedtls/config/mbedtls_preset_default.conf @@ -42,7 +42,6 @@ CONFIG_MBEDTLS_X509_RSASSA_PSS_SUPPORT=y CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK=n CONFIG_MBEDTLS_ASN1_PARSE_C=y CONFIG_MBEDTLS_ASN1_WRITE_C=y -CONFIG_MBEDTLS_OID_C=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=n @@ -75,12 +74,9 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=n CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=n CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=n CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_SSL_MAX_FRAGMENT_LENGTH=y @@ -93,9 +89,6 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y # DTLS Protocol Configuration CONFIG_MBEDTLS_SSL_PROTO_DTLS=n -# Cipher Abstraction Layer -CONFIG_MBEDTLS_CIPHER_C=n - # Symmetric Ciphers CONFIG_MBEDTLS_AES_C=y CONFIG_MBEDTLS_CAMELLIA_C=n @@ -111,12 +104,7 @@ CONFIG_MBEDTLS_CIPHER_MODE_OFB=y CONFIG_MBEDTLS_CIPHER_MODE_XTS=y CONFIG_MBEDTLS_GCM_C=y CONFIG_MBEDTLS_NIST_KW_C=n -CONFIG_MBEDTLS_CIPHER_PADDING=y -CONFIG_MBEDTLS_CIPHER_PADDING_PKCS7=y CONFIG_MBEDTLS_PKCS5_C=y -CONFIG_MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS=y -CONFIG_MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN=y -CONFIG_MBEDTLS_CIPHER_PADDING_ZEROS=y CONFIG_MBEDTLS_AES_ROM_TABLES=y CONFIG_MBEDTLS_AES_FEWER_TABLES=n CONFIG_MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH=n @@ -130,7 +118,6 @@ CONFIG_MBEDTLS_RSA_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=n -CONFIG_MBEDTLS_DHM_C=y CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECJPAKE_C=n CONFIG_MBEDTLS_ECDSA_C=y @@ -138,13 +125,9 @@ CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y CONFIG_MBEDTLS_ECP_RESTARTABLE=n -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y @@ -166,7 +149,6 @@ CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_AES_USE_INTERRUPT=y CONFIG_MBEDTLS_AES_INTERRUPT_LEVEL=0 -CONFIG_MBEDTLS_PK_RSA_ALT_SUPPORT=y CONFIG_MBEDTLS_HARDWARE_MPI=y # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI=n CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y @@ -179,11 +161,9 @@ CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN=n CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY=n CONFIG_MBEDTLS_PKCS7_C=y -CONFIG_MBEDTLS_PKCS12_C=y CONFIG_MBEDTLS_PKCS1_V15=y CONFIG_MBEDTLS_PKCS1_V21=y -CONFIG_MBEDTLS_ENTROPY_C=y CONFIG_MBEDTLS_ENTROPY_FORCE_SHA256=n CONFIG_MBEDTLS_CTR_DRBG_C=y CONFIG_MBEDTLS_HMAC_DRBG_C=y @@ -192,7 +172,6 @@ CONFIG_MBEDTLS_BASE64_C=y CONFIG_MBEDTLS_CHACHA20_C=n CONFIG_MBEDTLS_POLY1305_C=n -CONFIG_MBEDTLS_HKDF_C=n # # End of mbedTLS Minimal Configuration Preset diff --git a/components/mbedtls/config/mbedtls_preset_minimal.conf b/components/mbedtls/config/mbedtls_preset_minimal.conf index 1b44f12e2b7..59a375098d5 100644 --- a/components/mbedtls/config/mbedtls_preset_minimal.conf +++ b/components/mbedtls/config/mbedtls_preset_minimal.conf @@ -35,9 +35,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=n CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=n CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=n -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=n CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=n -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=n CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=n CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=n CONFIG_MBEDTLS_SSL_ALPN=n @@ -46,10 +44,6 @@ CONFIG_MBEDTLS_SSL_RENEGOTIATION=n CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=n CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=n - -# Cipher Abstraction Layer -CONFIG_MBEDTLS_CIPHER_C=y - # Symmetric Ciphers CONFIG_MBEDTLS_ARIA_C=n CONFIG_MBEDTLS_BLOWFISH_C=n @@ -57,12 +51,7 @@ CONFIG_MBEDTLS_CCM_C=n CONFIG_MBEDTLS_CIPHER_MODE_OFB=n CONFIG_MBEDTLS_CIPHER_MODE_XTS=y CONFIG_MBEDTLS_GCM_C=n -CONFIG_MBEDTLS_CIPHER_PADDING=n -CONFIG_MBEDTLS_CIPHER_PADDING_PKCS7=n CONFIG_MBEDTLS_PKCS5_C=n -CONFIG_MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS=n -CONFIG_MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN=n -CONFIG_MBEDTLS_CIPHER_PADDING_ZEROS=n CONFIG_MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH=y CONFIG_MBEDTLS_CMAC_C=n @@ -72,19 +61,14 @@ CONFIG_MBEDTLS_RSA_C=y # Elliptic Curve Ciphers Configuration CONFIG_MBEDTLS_ECP_C=n CONFIG_MBEDTLS_ECP_NIST_OPTIM=n -CONFIG_MBEDTLS_DHM_C=n CONFIG_MBEDTLS_ECDH_C=n CONFIG_MBEDTLS_ECDSA_C=n CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=n CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=n CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=n -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=n -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=n -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=n -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=n CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=n diff --git a/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c b/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c index 3e68dcccfb9..05eff00b9cb 100644 --- a/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c +++ b/components/mbedtls/esp_crt_bundle/esp_crt_bundle.c @@ -17,6 +17,9 @@ #include "sdkconfig.h" +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" + /* Format of certificate bundle: First, n uint32 "offset" entries, each describing the start of one certificate's data in terms of @@ -131,6 +134,10 @@ static int esp_crt_check_signature(const mbedtls_x509_crt* child, const uint8_t* int ret = 0; mbedtls_pk_context pubkey; const mbedtls_md_info_t *md_info; + psa_key_id_t key_id = 0; + psa_status_t status; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + bool key_imported = false; mbedtls_pk_init(&pubkey); @@ -139,37 +146,125 @@ static int esp_crt_check_signature(const mbedtls_x509_crt* child, const uint8_t* goto cleanup; } - // Fast check to avoid expensive computations when not necessary - if (unlikely(!mbedtls_pk_can_do(&pubkey, child->MBEDTLS_PRIVATE(sig_pk)))) { - ESP_LOGE(TAG, "Unsuitable public key"); - ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; - goto cleanup; - } - + // Get the message digest info for the hash algorithm used in the certificate + // We need to know this BEFORE importing the key so we can set the correct algorithm md_info = mbedtls_md_info_from_type(child->MBEDTLS_PRIVATE(sig_md)); - if (unlikely(md_info == NULL)) { - ESP_LOGE(TAG, "Unknown message digest"); + ESP_LOGE(TAG, "Unknown message digest type: %d", child->MBEDTLS_PRIVATE(sig_md)); ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; goto cleanup; } + // Map mbedTLS MD type to PSA hash algorithm + psa_algorithm_t psa_hash_alg; + switch (child->MBEDTLS_PRIVATE(sig_md)) { + case MBEDTLS_MD_SHA256: + psa_hash_alg = PSA_ALG_SHA_256; + break; + case MBEDTLS_MD_SHA384: + psa_hash_alg = PSA_ALG_SHA_384; + break; + case MBEDTLS_MD_SHA512: + psa_hash_alg = PSA_ALG_SHA_512; + break; + case MBEDTLS_MD_SHA1: + psa_hash_alg = PSA_ALG_SHA_1; + break; + default: + ESP_LOGE(TAG, "Unsupported hash algorithm: %d", child->MBEDTLS_PRIVATE(sig_md)); + ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; + goto cleanup; + } + + // Get the appropriate key attributes for signature verification + ret = mbedtls_pk_get_psa_attributes(&pubkey, PSA_KEY_USAGE_VERIFY_HASH, &key_attr); + if (unlikely(ret != 0)) { + ESP_LOGE(TAG, "Failed to get PSA key attributes with error 0x%x", -ret); + goto cleanup; + } + + // Determine the PSA algorithm based on the key type and hash type + // We need to set this BEFORE importing the key + psa_algorithm_t psa_alg; + psa_key_type_t key_type = psa_get_key_type(&key_attr); + + ESP_LOGD(TAG, "Key type: 0x%x, Hash alg: 0x%x", + (unsigned int)key_type, (unsigned int)psa_hash_alg); + + if (PSA_KEY_TYPE_IS_RSA(key_type)) { + // For RSA keys, use PKCS#1 v1.5 with the specific hash algorithm + psa_alg = PSA_ALG_RSA_PKCS1V15_SIGN(psa_hash_alg); + ESP_LOGD(TAG, "Using RSA PKCS1V15 SIGN algorithm with hash"); + } else if (PSA_KEY_TYPE_IS_ECC(key_type)) { + // For ECC keys, use ECDSA_ANY which works with psa_verify_hash + // and doesn't constrain the hash length + psa_alg = PSA_ALG_ECDSA_ANY; + ESP_LOGD(TAG, "Using ECDSA_ANY algorithm (no hash constraint)"); + } else { + ESP_LOGE(TAG, "Unsupported key type: 0x%x", (unsigned int)key_type); + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + goto cleanup; + } + + // Override the algorithm in key attributes with the specific hash algorithm + // This is required because PSA_ALG_ANY_HASH wildcard doesn't work for verification + psa_set_key_algorithm(&key_attr, psa_alg); + + // Import the public key into PSA + ret = mbedtls_pk_import_into_psa(&pubkey, &key_attr, &key_id); + if (unlikely(ret != 0)) { + ESP_LOGE(TAG, "Failed to import key into PSA with error 0x%x", -ret); + goto cleanup; + } + key_imported = true; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; const unsigned char md_size = mbedtls_md_get_size(md_info); - if ((ret = mbedtls_md(md_info, child->tbs.p, child->tbs.len, hash)) != 0) { - ESP_LOGE(TAG, "MD failed with error 0x%x", -ret); + size_t hash_len = 0; + status = psa_hash_compute(psa_hash_alg, child->tbs.p, child->tbs.len, hash, sizeof(hash), &hash_len); + + unsigned char *sig_ptr = child->MBEDTLS_PRIVATE(sig).p; + size_t sig_len = child->MBEDTLS_PRIVATE(sig).len; + unsigned char raw_sig[MBEDTLS_ECDSA_MAX_LEN]; + + if (PSA_KEY_TYPE_IS_ECC(key_type)) { + // Convert DER-encoded ECDSA signature to raw (r||s) format for PSA + // Get the key size in bits from PSA attributes + size_t key_bits = psa_get_key_bits(&key_attr); + ret = mbedtls_ecdsa_der_to_raw(key_bits, + child->MBEDTLS_PRIVATE(sig).p, + child->MBEDTLS_PRIVATE(sig).len, + raw_sig, sizeof(raw_sig), &sig_len); + if (ret != 0) { + ESP_LOGE(TAG, "Failed to convert ECDSA signature to raw format: 0x%x (returned %d)", -ret, ret); + ret = MBEDTLS_ERR_X509_INVALID_SIGNATURE; + goto cleanup; + } + sig_ptr = raw_sig; + ESP_LOGD(TAG, "Converted DER signature (len=%zu) to raw format (len=%zu) for %zu-bit key", + child->MBEDTLS_PRIVATE(sig).len, sig_len, key_bits); + } + + // Verify the signature using PSA with the correct algorithm + ESP_LOGD(TAG, "Verifying signature: alg=0x%08x, hash_len=%d, sig_len=%zu", + (unsigned int)psa_alg, md_size, sig_len); + status = psa_verify_hash(key_id, psa_alg, hash, md_size, sig_ptr, sig_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "PSA signature verification failed with error 0x%x (decimal: %d)", + (unsigned int)status, (int)status); + ret = MBEDTLS_ERR_X509_INVALID_SIGNATURE; goto cleanup; } - if (unlikely((ret = mbedtls_pk_verify_ext(child->MBEDTLS_PRIVATE(sig_pk), child->MBEDTLS_PRIVATE(sig_opts), &pubkey, - child->MBEDTLS_PRIVATE(sig_md), hash, md_size, - child->MBEDTLS_PRIVATE(sig).p, child->MBEDTLS_PRIVATE(sig).len)) != 0)) { - ESP_LOGE(TAG, "PK verify failed with error 0x%x", -ret); - goto cleanup; - } + ret = 0; + ESP_LOGD(TAG, "Certificate signature verified successfully"); cleanup: + if (key_imported) { + psa_destroy_key(key_id); + } + psa_reset_key_attributes(&key_attr); mbedtls_pk_free(&pubkey); return ret; } @@ -229,7 +324,6 @@ int esp_crt_verify_callback(void *buf, mbedtls_x509_crt* const crt, const int de return 0; } - if (unlikely(s_crt_bundle == NULL)) { ESP_LOGE(TAG, "No certificates in bundle"); return MBEDTLS_ERR_X509_FATAL_ERROR; @@ -405,7 +499,8 @@ static int esp_crt_ca_cb_callback(void *ctx, mbedtls_x509_crt const *child, mbed uint16_t cert_key_len = esp_crt_get_key_len(cert); // Set the public key in the new certificate mbedtls_pk_init(&new_cert->pk); - int ret = mbedtls_pk_parse_subpubkey((unsigned char **)&cert_key, cert_key + cert_key_len, &new_cert->pk); + // Use mbedtls_pk_parse_public_key() instead of deprecated mbedtls_pk_parse_subpubkey() + int ret = mbedtls_pk_parse_public_key(&new_cert->pk, cert_key, cert_key_len); if (ret != 0) { ESP_LOGE(TAG, "Failed to parse public key from certificate: %d", ret); mbedtls_x509_crt_free(new_cert); diff --git a/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c index 16ed38ba25a..2c4e7e0b32d 100644 --- a/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c +++ b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c @@ -7,7 +7,6 @@ #include "esp_err.h" -#include "mbedtls/aes.h" #include "esp_crypto_dma.h" #include "soc/soc_caps.h" diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake index 4f62a1f9b02..91fb959acc2 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake @@ -31,47 +31,82 @@ include_directories("${COMPONENT_DIR}/port/include") # Import mbedtls library targets add_subdirectory(mbedtls) -set(mbedtls_targets mbedcrypto) +# Set TF_PSA_CRYPTO_CONFIG_FILE before processing subdirectories to prevent override +set( + TF_PSA_CRYPTO_USER_CONFIG_FILE "${COMPONENT_DIR}/esp_tee/esp_tee_mbedtls_config.h" + CACHE STRING "Path to the PSA Crypto configuration file" + FORCE +) + +set(mbedtls_targets mbedtls tfpsacrypto builtin mbedx509 everest p256m) + +target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c") foreach(target ${mbedtls_targets}) target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="${COMPONENT_DIR}/esp_tee/esp_tee_mbedtls_config.h") + set_config_files_compile_definitions(${target}) + target_compile_definitions(${target} PUBLIC MBEDTLS_MAJOR_VERSION=4) + if(CONFIG_COMPILER_STATIC_ANALYZER AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # TODO IDF-10087 + target_compile_options(${target} PRIVATE "-fno-analyzer") + endif() + if(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_SIZE) + message(STATUS "Setting -Os for ${target}") + target_compile_options(${target} PRIVATE "-Os") + elseif(CONFIG_MBEDTLS_COMPILER_OPTIMIZATION_PERF) + target_compile_options(${target} PRIVATE "-O2") + endif() endforeach() target_link_libraries(${COMPONENT_LIB} INTERFACE ${mbedtls_targets}) -target_link_libraries(mbedcrypto PRIVATE idf::esp_security) +target_link_libraries(tfpsacrypto PRIVATE idf::esp_security) -target_include_directories(mbedcrypto PRIVATE ${crypto_port_inc_dirs}) +target_include_directories(tfpsacrypto PRIVATE ${crypto_port_inc_dirs}) # Shared GDMA layer for TEE -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/esp_tee/esp_tee_crypto_shared_gdma.c") +target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/esp_tee/esp_tee_crypto_shared_gdma.c") +target_include_directories(tfpsacrypto PUBLIC "${COMPONENT_DIR}/port/psa_driver/include") # AES implementation if(CONFIG_SOC_AES_SUPPORTED) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes.c" - "${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c" - "${COMPONENT_DIR}/port/aes/esp_aes_common.c" - "${COMPONENT_DIR}/port/aes/esp_aes_xts.c" - "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c") -endif() + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes.c" + "${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c") + target_compile_definitions(tfpsacrypto PRIVATE ESP_AES_DRIVER_ENABLED) + target_include_directories(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/include/aes") + if(CONFIG_MBEDTLS_HARDWARE_SHA) + target_sources(tfpsacrypto PRIVATE + "${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c" + "${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c" + ) + endif() + if(CONFIG_SOC_AES_SUPPORT_GCM) + target_sources(tfpsacrypto PRIVATE "$ENV{IDF_PATH}/components/mbedtls/port/aes/esp_aes_gcm.c" + "${COMPONENT_DIR}/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c") + endif() + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_common.c" + "${COMPONENT_DIR}/port/aes/esp_aes_xts.c" + "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c") +endif() # SHA implementation if(CONFIG_SOC_SHA_SUPPORTED) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/core/esp_sha1.c" - "${COMPONENT_DIR}/port/sha/core/esp_sha256.c" - "${COMPONENT_DIR}/port/sha/core/esp_sha512.c" - "${COMPONENT_DIR}/port/sha/core/sha.c" - "${COMPONENT_DIR}/port/sha/esp_sha.c") + 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/core/psa_crypto_driver_esp_sha1.c" + "${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c" + "${COMPONENT_DIR}/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c" + "${COMPONENT_DIR}/port/sha/core/sha.c" + "${COMPONENT_DIR}/port/sha/esp_sha.c") endif() -# ECC implementation if(CONFIG_SOC_ECC_SUPPORTED) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecc/esp_ecc.c" - "${COMPONENT_DIR}/port/ecc/ecc_alt.c") + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/ecc/esp_ecc.c" + "${COMPONENT_DIR}/port/ecc/ecc_alt.c") endif() -# HMAC-based PBKDF2 implementation if(CONFIG_SOC_HMAC_SUPPORTED) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c") + # HMAC-based PBKDF2 implementation + target_sources(tfpsacrypto PRIVATE "${COMPONENT_DIR}/port/esp_hmac_pbkdf2.c") endif() diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index d8ea8ff8460..1a9a6afcf26 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -28,21 +28,20 @@ #ifndef ESP_TEE_MBEDTLS_CONFIG_H #define ESP_TEE_MBEDTLS_CONFIG_H -#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS +#ifndef CONFIG_IDF_TARGET_LINUX +#undef MBEDTLS_PSA_BUILTIN_GET_ENTROPY +#define MBEDTLS_PSA_DRIVER_GET_ENTROPY +#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG +#endif // !CONFIG_IDF_TARGET_LINUX +#undef MBEDTLS_PSA_KEY_STORE_DYNAMIC + #define MBEDTLS_HAVE_TIME #define MBEDTLS_PLATFORM_MS_TIME_ALT #undef MBEDTLS_TIMING_C #define MBEDTLS_PLATFORM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_AES_C -#define MBEDTLS_GCM_C -#if SOC_AES_SUPPORTED -#define MBEDTLS_AES_ALT -#define MBEDTLS_GCM_ALT -#else -#define MBEDTLS_AES_ROM_TABLES -#endif +#define MBEDTLS_PSA_ACCEL_KEY_TYPE_AES #define MBEDTLS_CIPHER_MODE_XTS #define MBEDTLS_ASN1_WRITE_C @@ -60,19 +59,19 @@ #endif #define MBEDTLS_SHA224_C #define MBEDTLS_SHA256_C -#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C -#define MBEDTLS_SHA384_C -#define MBEDTLS_SHA512_C -#endif #if SOC_SHA_SUPPORTED #if CONFIG_MBEDTLS_SHA1_C -#define MBEDTLS_SHA1_ALT -#endif -#define MBEDTLS_SHA256_ALT -#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C -#define MBEDTLS_SHA512_ALT + #define MBEDTLS_PSA_ACCEL_ALG_SHA_1 + #undef MBEDTLS_PSA_BUILTIN_ALG_SHA_1 + #undef MBEDTLS_SHA1_C #endif +#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_224 +#undef MBEDTLS_SHA224_C +#define MBEDTLS_PSA_ACCEL_ALG_SHA_224 +#undef MBEDTLS_PSA_BUILTIN_ALG_SHA_256 +#define MBEDTLS_PSA_ACCEL_ALG_SHA_256 +#undef MBEDTLS_SHA256_C #endif #if SOC_ECC_SUPPORTED @@ -80,10 +79,66 @@ #define MBEDTLS_ECP_VERIFY_ALT #endif -#if !SOC_HMAC_SUPPORTED -#define MBEDTLS_MD_C -#endif +#undef PSA_WANT_ECC_SECP_K1_192 +#undef PSA_WANT_ECC_SECP_K1_256 +#undef PSA_WANT_ECC_SECP_R1_224 +#undef PSA_WANT_ECC_SECP_R1_384 +#undef PSA_WANT_ECC_SECP_R1_521 +#undef PSA_WANT_ECC_BRAINPOOL_P_R1_256 +#undef PSA_WANT_ECC_BRAINPOOL_P_R1_384 +#undef PSA_WANT_ECC_BRAINPOOL_P_R1_512 +#undef MBEDTLS_ECP_DP_BP256R1_ENABLED +#undef MBEDTLS_ECP_DP_BP384R1_ENABLED +#undef MBEDTLS_ECP_DP_BP512R1_ENABLED +#undef MBEDTLS_ECP_DP_SECP192K1_ENABLED +#undef MBEDTLS_ECP_DP_SECP224K1_ENABLED +#undef MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ENTROPY_C + +#undef PSA_WANT_KEY_TYPE_HMAC +#undef PSA_WANT_KEY_TYPE_ARIA +#undef PSA_WANT_KEY_TYPE_CAMELLIA +#undef MBEDTLS_CAMELLIA_C +#undef MBEDTLS_DES_C +#undef PSA_WANT_ALG_RIPEMD160 +#undef MBEDTLS_RIPEMD160_C +#undef PSA_WANT_ALG_MD5 +#undef MBEDTLS_MD5_C +#undef PSA_WANT_ALG_CHACHA20 +#undef MBEDTLS_CHACHA20_C +#undef PSA_WANT_ALG_SHA3_224 +#undef MBEDTLS_SHA3_224_C +#undef PSA_WANT_ALG_SHA3_256 +#undef MBEDTLS_SHA3_256_C +#undef PSA_WANT_ALG_SHA3_384 +#undef MBEDTLS_SHA3_384_C +#undef PSA_WANT_ALG_SHA3_512 +#undef MBEDTLS_SHA3_512_C + +#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC +#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT +#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT +#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +#undef MBEDTLS_RSA_C + +#undef PSA_WANT_ALG_FFDH +#undef MBEDTLS_ARIA_C +#undef MBEDTLS_CCM_C +#undef MBEDTLS_CHACHA20_C +#undef MBEDTLS_CHACHAPOLY_C +#undef MBEDTLS_DEBUG_C + +#define MBEDTLS_SSL_CLI_C +#undef MBEDTLS_SSL_SRV_C + +#undef PSA_WANT_ALG_PBKDF2_HMAC +#undef PSA_WANT_ALG_TLS12_PRF +#undef PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 +#undef PSA_WANT_ALG_CCM +#undef PSA_WANT_ALG_CMAC +#undef PSA_WANT_KEY_TYPE_DES + +#undef MBEDTLS_AES_C +#define MBEDTLS_AES_ROM_TABLES #endif /* ESP_TEE_MBEDTLS_CONFIG_H */ diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index ffb280bb63c..66753bb91ff 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit ffb280bb63c78bfec1e1ab55040671768c85c923 +Subproject commit 66753bb91ffbdaa7c75bfb693d626732ecdf6b2c diff --git a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c index 2a2780b8ccd..a7ad0926eac 100644 --- a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c +++ b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c @@ -24,7 +24,7 @@ #include "esp_aes_internal.h" #include "esp_crypto_dma.h" -#include "mbedtls/aes.h" +#include "psa/crypto.h" #include "mbedtls/platform_util.h" #if !ESP_TEE_BUILD @@ -37,6 +37,8 @@ #include "freertos/semphr.h" #endif +#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ + #if SOC_AES_SUPPORT_GCM #include "aes/esp_aes_gcm.h" #endif diff --git a/components/mbedtls/port/aes/esp_aes.c b/components/mbedtls/port/aes/esp_aes.c index e874102a52f..9b73eac8bfe 100644 --- a/components/mbedtls/port/aes/esp_aes.c +++ b/components/mbedtls/port/aes/esp_aes.c @@ -16,7 +16,6 @@ */ #include -#include "mbedtls/aes.h" #include "esp_log.h" #include "esp_crypto_lock.h" #include "hal/aes_hal.h" @@ -24,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() @@ -34,6 +34,10 @@ #include "hal/crypto_dma_ll.h" #endif +#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 /**< Invalid input data. */ +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ +#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ + static const char *TAG = "esp-aes"; #if CONFIG_MBEDTLS_AES_HW_SMALL_DATA_LEN_OPTIM @@ -132,6 +136,7 @@ static int esp_aes_block(esp_aes_context *ctx, const void *input, void *output) */ if (ctx->key_in_hardware != ctx->key_bytes) { mbedtls_platform_zeroize(output, 16); + memset(output, 0, 16); return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; } i0 = input_words[0]; diff --git a/components/mbedtls/port/aes/esp_aes_common.c b/components/mbedtls/port/aes/esp_aes_common.c index 47da4407279..976e2a71463 100644 --- a/components/mbedtls/port/aes/esp_aes_common.c +++ b/components/mbedtls/port/aes/esp_aes_common.c @@ -15,15 +15,17 @@ * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf */ #include "sdkconfig.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "esp_aes_internal.h" -#include "mbedtls/aes.h" #include "hal/aes_hal.h" #include "hal/aes_types.h" #include "soc/soc_caps.h" -#include "mbedtls/error.h" +#include "psa/crypto.h" #include +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 + #if SOC_AES_SUPPORT_DMA #include "esp_aes_dma_priv.h" #endif @@ -65,7 +67,7 @@ int esp_aes_setkey( esp_aes_context *ctx, const unsigned char *key, { #if !SOC_AES_SUPPORT_AES_192 if (keybits == 192) { - return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; + return PSA_ERROR_NOT_SUPPORTED; } #endif if (keybits != 128 && keybits != 192 && keybits != 256) { diff --git a/components/mbedtls/port/aes/esp_aes_gcm.c b/components/mbedtls/port/aes/esp_aes_gcm.c index 839fb71a1fb..ff40afbd3bc 100644 --- a/components/mbedtls/port/aes/esp_aes_gcm.c +++ b/components/mbedtls/port/aes/esp_aes_gcm.c @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2025 Espressif Systems (Shanghai) CO LTD */ /* * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. @@ -15,14 +15,12 @@ * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf */ #include - +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "aes/esp_aes.h" #include "aes/esp_aes_gcm.h" #include "esp_aes_internal.h" #include "hal/aes_hal.h" -#include "mbedtls/aes.h" -#include "mbedtls/error.h" #include "mbedtls/gcm.h" #include "esp_heap_caps.h" @@ -32,10 +30,14 @@ #include "sdkconfig.h" +#include "psa/crypto.h" + #if SOC_AES_SUPPORT_DMA #include "esp_aes_dma_priv.h" #endif +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 + #define ESP_PUT_BE64(a, val) \ do { \ *(uint64_t*)(a) = __builtin_bswap64( (uint64_t)(val) ); \ @@ -252,34 +254,13 @@ static void gcm_mult( esp_gcm_context *ctx, const unsigned char x[16], /* Update the key value in gcm context */ int esp_aes_gcm_setkey( esp_gcm_context *ctx, - mbedtls_cipher_id_t cipher, + int cipher, const unsigned char *key, unsigned int keybits ) { - /* Fallback to software implementation of GCM operation when a non-AES - * cipher is selected, as we support hardware acceleration only for a - * GCM operation using AES cipher. - */ -#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) - if (ctx->ctx_soft != NULL) { - mbedtls_gcm_free_soft(ctx->ctx_soft); - free(ctx->ctx_soft); - ctx->ctx_soft = NULL; - } - - if (cipher != MBEDTLS_CIPHER_ID_AES) { - ctx->ctx_soft = (mbedtls_gcm_context_soft*) malloc(sizeof(mbedtls_gcm_context_soft)); - if (ctx->ctx_soft == NULL) { - return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; - } - mbedtls_gcm_init_soft(ctx->ctx_soft); - return mbedtls_gcm_setkey_soft(ctx->ctx_soft, cipher, key, keybits); - } -#endif - #if !SOC_AES_SUPPORT_AES_192 if (keybits == 192) { - return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; + return PSA_ERROR_NOT_SUPPORTED; } #endif if (keybits != 128 && keybits != 192 && keybits != 256) { @@ -358,14 +339,6 @@ void esp_aes_gcm_free( esp_gcm_context *ctx) if (ctx == NULL) { return; } -#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) - if (ctx->ctx_soft != NULL) { - mbedtls_gcm_free_soft(ctx->ctx_soft); - free(ctx->ctx_soft); - /* Note that the value of ctx->ctx_soft should be NULL'ed out - and here it is taken care by the bzero call below */ - } -#endif bzero(ctx, sizeof(esp_gcm_context)); } @@ -377,25 +350,19 @@ int esp_aes_gcm_starts( esp_gcm_context *ctx, { if (!ctx) { ESP_LOGE(TAG, "No AES context supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } -#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) - if (ctx->ctx_soft != NULL) { - return mbedtls_gcm_starts_soft(ctx->ctx_soft, mode, iv, iv_len); - } -#endif - /* IV is limited to 2^32 bits, so 2^29 bytes */ /* IV is not allowed to be zero length */ if ( iv_len == 0 || ( (uint32_t) iv_len ) >> 29 != 0 ) { - return ( MBEDTLS_ERR_GCM_BAD_INPUT ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } if (!iv) { ESP_LOGE(TAG, "No IV supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return -PSA_ERROR_INVALID_ARGUMENT; } /* Initialize AES-GCM context */ @@ -421,7 +388,7 @@ int esp_aes_gcm_starts( esp_gcm_context *ctx, esp_aes_release_hardware(); #else memset(ctx->H, 0, sizeof(ctx->H)); - int ret = esp_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->H, ctx->H); + int ret = esp_aes_crypt_ecb(&ctx->aes_ctx, ESP_AES_ENCRYPT, ctx->H, ctx->H); if (ret != 0) { return ret; } @@ -449,28 +416,22 @@ int esp_aes_gcm_update_ad( esp_gcm_context *ctx, { if (!ctx) { ESP_LOGE(TAG, "No AES context supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } -#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) - if (ctx->ctx_soft != NULL) { - return mbedtls_gcm_update_ad_soft(ctx->ctx_soft, aad, aad_len); - } -#endif - /* AD are limited to 2^32 bits, so 2^29 bytes */ if ( ( (uint32_t) aad_len ) >> 29 != 0 ) { - return ( MBEDTLS_ERR_GCM_BAD_INPUT ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } if ( (aad_len > 0) && !aad) { ESP_LOGE(TAG, "No aad supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } if (ctx->gcm_state != ESP_AES_GCM_STATE_START) { ESP_LOGE(TAG, "AES context in invalid state!"); - return -1; + return PSA_ERROR_BAD_STATE; } /* Initialise associated data */ @@ -490,36 +451,30 @@ int esp_aes_gcm_update( esp_gcm_context *ctx, { if (!ctx) { ESP_LOGE(TAG, "No GCM context supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return -1; } -#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) - if (ctx->ctx_soft != NULL) { - return mbedtls_gcm_update_soft(ctx->ctx_soft, input, input_length, output, output_size, output_length); - } -#endif - size_t nc_off = 0; uint8_t nonce_counter[AES_BLOCK_BYTES] = {0}; uint8_t stream[AES_BLOCK_BYTES] = {0}; if (!output_length) { ESP_LOGE(TAG, "No output length supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } *output_length = input_length; if (!input) { ESP_LOGE(TAG, "No input supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } if (!output) { ESP_LOGE(TAG, "No output supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } if ( output > input && (size_t) ( output - input ) < input_length ) { - return ( MBEDTLS_ERR_GCM_BAD_INPUT ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } /* If this is the first time esp_gcm_update is getting called * calculate GHASH on aad and preincrement the ICB @@ -565,17 +520,12 @@ int esp_aes_gcm_finish( esp_gcm_context *ctx, size_t *output_length, unsigned char *tag, size_t tag_len ) { -#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) - if (ctx->ctx_soft != NULL) { - return mbedtls_gcm_finish_soft(ctx->ctx_soft, output, output_size, output_length, tag, tag_len); - } -#endif size_t nc_off = 0; uint8_t len_block[AES_BLOCK_BYTES] = {0}; uint8_t stream[AES_BLOCK_BYTES] = {0}; if ( tag_len > 16 || tag_len < 4 ) { - return ( MBEDTLS_ERR_GCM_BAD_INPUT ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } /* Calculate final GHASH on aad_len, data length */ @@ -663,14 +613,8 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx, { if (!ctx) { ESP_LOGE(TAG, "No AES context supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } - -#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) - if (ctx->ctx_soft != NULL) { - return mbedtls_gcm_crypt_and_tag_soft(ctx->ctx_soft, mode, length, iv, iv_len, aad, aad_len, input, output, tag_len, tag); - } -#endif #if CONFIG_MBEDTLS_HARDWARE_GCM int ret; size_t remainder_bit; @@ -687,24 +631,24 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx, Maximum size of data in the buffer that a DMA descriptor can hold. */ if (aad_len > DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) { - return MBEDTLS_ERR_GCM_BAD_INPUT; + return -1; } /* IV and AD are limited to 2^32 bits, so 2^29 bytes */ /* IV is not allowed to be zero length */ if ( iv_len == 0 || ( (uint32_t) iv_len ) >> 29 != 0 || ( (uint32_t) aad_len ) >> 29 != 0 ) { - return ( MBEDTLS_ERR_GCM_BAD_INPUT ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } if (!iv) { ESP_LOGE(TAG, "No IV supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } if ( (aad_len > 0) && !aad) { ESP_LOGE(TAG, "No aad supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; + return PSA_ERROR_INVALID_ARGUMENT; } /* Initialize AES-GCM context */ @@ -761,11 +705,6 @@ int esp_aes_gcm_auth_decrypt( esp_gcm_context *ctx, const unsigned char *input, unsigned char *output ) { -#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) - if (ctx->ctx_soft != NULL) { - return mbedtls_gcm_auth_decrypt_soft(ctx->ctx_soft, length, iv, iv_len, aad, aad_len, tag, tag_len, input, output); - } -#endif int ret; unsigned char check_tag[16]; size_t i; @@ -784,7 +723,7 @@ int esp_aes_gcm_auth_decrypt( esp_gcm_context *ctx, if ( diff != 0 ) { bzero( output, length ); - return ( MBEDTLS_ERR_GCM_AUTH_FAILED ); + return ( PSA_ERROR_INVALID_SIGNATURE ); } return ( 0 ); diff --git a/components/mbedtls/port/aes/esp_aes_xts.c b/components/mbedtls/port/aes/esp_aes_xts.c index 4b4663162f7..29fd00f2830 100644 --- a/components/mbedtls/port/aes/esp_aes_xts.c +++ b/components/mbedtls/port/aes/esp_aes_xts.c @@ -36,9 +36,9 @@ #include #include #include -#include "mbedtls/aes.h" - +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "aes/esp_aes.h" +#include "psa/crypto.h" void esp_aes_xts_init( esp_aes_xts_context *ctx ) { @@ -65,7 +65,7 @@ static int esp_aes_xts_decode_keys( const unsigned char *key, switch ( keybits ) { case 256: break; case 512: break; - default : return ( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + default : return ( PSA_ERROR_NOT_SUPPORTED ); } *key1bits = half_keybits; @@ -124,7 +124,7 @@ int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx, return esp_aes_setkey( &ctx->crypt, key1, key1bits ); } -/* Endianess with 64 bits values */ +/* Endianness with 64 bits values */ #ifndef GET_UINT64_LE #define GET_UINT64_LE(n,b,i) \ { \ @@ -158,7 +158,7 @@ int esp_aes_xts_setkey_dec( esp_aes_xts_context *ctx, * * This function multiplies a field element by x in the polynomial field * representation. It uses 64-bit word operations to gain speed but compensates - * for machine endianess and hence works correctly on both big and little + * for machine endianness and hence works correctly on both big and little * endian machines. */ static void esp_gf128mul_x_ble( unsigned char r[16], @@ -195,16 +195,16 @@ int esp_aes_crypt_xts( esp_aes_xts_context *ctx, /* Sectors must be at least 16 bytes. */ if ( length < 16 ) { - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + return PSA_ERROR_DATA_INVALID; } /* NIST SP 80-38E disallows data units larger than 2**20 blocks. */ if ( length > ( 1 << 20 ) * 16 ) { - return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + return PSA_ERROR_DATA_INVALID; } /* Compute the tweak. */ - ret = esp_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT, + ret = esp_aes_crypt_ecb( &ctx->tweak, ESP_AES_ENCRYPT, data_unit, tweak ); if ( ret != 0 ) { return ( ret ); @@ -213,7 +213,7 @@ int esp_aes_crypt_xts( esp_aes_xts_context *ctx, while ( blocks-- ) { size_t i; - if ( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) { + if ( leftover && ( mode == ESP_AES_DECRYPT ) && blocks == 0 ) { /* We are on the last block in a decrypt operation that has * leftover bytes, so we need to use the next tweak for this block, * and this tweak for the lefover bytes. Save the current tweak for @@ -246,7 +246,7 @@ int esp_aes_crypt_xts( esp_aes_xts_context *ctx, if ( leftover ) { /* If we are on the leftover bytes in a decrypt operation, we need to * use the previous tweak for these bytes (as saved in prev_tweak). */ - unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; + unsigned char *t = mode == ESP_AES_DECRYPT ? prev_tweak : tweak; /* We are now on the final part of the data unit, which doesn't divide * evenly by 16. It's time for ciphertext stealing. */ @@ -254,7 +254,7 @@ int esp_aes_crypt_xts( esp_aes_xts_context *ctx, unsigned char *prev_output = output - 16; /* Copy ciphertext bytes from the previous block to our output for each - * byte of cyphertext we won't steal. At the same time, copy the + * byte of ciphertext we won't steal. At the same time, copy the * remainder of the input for this final round (since the loop bounds * are the same). */ for ( i = 0; i < leftover; i++ ) { diff --git a/components/mbedtls/port/bignum/bignum_alt.c b/components/mbedtls/port/bignum/bignum_alt.c index 5717faf3b4c..d85a4280981 100644 --- a/components/mbedtls/port/bignum/bignum_alt.c +++ b/components/mbedtls/port/bignum/bignum_alt.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "esp_crypto_lock.h" #include "bignum_impl.h" #include "mbedtls/bignum.h" diff --git a/components/mbedtls/port/bignum/esp_bignum.c b/components/mbedtls/port/bignum/esp_bignum.c index 1c799b3c2ad..50b60bddebf 100644 --- a/components/mbedtls/port/bignum/esp_bignum.c +++ b/components/mbedtls/port/bignum/esp_bignum.c @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2025 Espressif Systems (Shanghai) CO LTD */ #include #include @@ -28,7 +28,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" - +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "bignum_impl.h" #include "mbedtls/bignum.h" @@ -54,89 +54,6 @@ static const __attribute__((unused)) char *TAG = "bignum"; #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ #define biL (ciL << 3) /* bits in limb */ -#if defined(CONFIG_MBEDTLS_MPI_USE_INTERRUPT) -static SemaphoreHandle_t op_complete_sem; -#if defined(CONFIG_PM_ENABLE) -static esp_pm_lock_handle_t s_pm_cpu_lock; -static esp_pm_lock_handle_t s_pm_sleep_lock; -#endif - -static IRAM_ATTR void esp_mpi_complete_isr(void *arg) -{ - BaseType_t higher_woken; - mpi_hal_clear_interrupt(); - - xSemaphoreGiveFromISR(op_complete_sem, &higher_woken); - if (higher_woken) { - portYIELD_FROM_ISR(); - } -} - - -static esp_err_t esp_mpi_isr_initialise(void) -{ - mpi_hal_clear_interrupt(); - mpi_hal_interrupt_enable(true); - if (op_complete_sem == NULL) { - static StaticSemaphore_t op_sem_buf; - op_complete_sem = xSemaphoreCreateBinaryStatic(&op_sem_buf); - if (op_complete_sem == NULL) { - ESP_LOGE(TAG, "Failed to create intr semaphore"); - return ESP_FAIL; - } - - const int isr_flags = esp_intr_level_to_flags(CONFIG_MBEDTLS_MPI_INTERRUPT_LEVEL); - - esp_err_t ret; - ret = esp_intr_alloc(ETS_RSA_INTR_SOURCE, isr_flags, esp_mpi_complete_isr, NULL, NULL); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to allocate RSA interrupt %d", ret); - - // This should be treated as fatal error as this API would mostly - // be invoked within mbedTLS interface. There is no way for the system - // to proceed if the MPI interrupt allocation fails here. - abort(); - } - } - - /* MPI is clocked proportionally to CPU clock, take power management lock */ -#ifdef CONFIG_PM_ENABLE - if (s_pm_cpu_lock == NULL) { - if (esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "mpi_sleep", &s_pm_sleep_lock) != ESP_OK) { - ESP_LOGE(TAG, "Failed to create PM sleep lock"); - return ESP_FAIL; - } - if (esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "mpi_cpu", &s_pm_cpu_lock) != ESP_OK) { - ESP_LOGE(TAG, "Failed to create PM CPU lock"); - return ESP_FAIL; - } - } - esp_pm_lock_acquire(s_pm_cpu_lock); - esp_pm_lock_acquire(s_pm_sleep_lock); -#endif - - return ESP_OK; -} - -static int esp_mpi_wait_intr(void) -{ - if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) { - ESP_LOGE("MPI", "Timed out waiting for completion of MPI Interrupt"); - return -1; - } - -#ifdef CONFIG_PM_ENABLE - esp_pm_lock_release(s_pm_cpu_lock); - esp_pm_lock_release(s_pm_sleep_lock); -#endif // CONFIG_PM_ENABLE - - mpi_hal_interrupt_enable(false); - - return 0; -} - -#endif // CONFIG_MBEDTLS_MPI_USE_INTERRUPT - /* Convert bit count to word count */ static inline size_t bits_to_words(size_t bits) @@ -148,6 +65,15 @@ static inline size_t bits_to_words(size_t bits) number. */ #if defined(MBEDTLS_MPI_EXP_MOD_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) + +#if defined(CONFIG_MBEDTLS_MPI_USE_INTERRUPT) +static SemaphoreHandle_t op_complete_sem; +#if defined(CONFIG_PM_ENABLE) +static esp_pm_lock_handle_t s_pm_cpu_lock; +static esp_pm_lock_handle_t s_pm_sleep_lock; +#endif +#endif // CONFIG_MBEDTLS_MPI_USE_INTERRUPT + static size_t mpi_words(const mbedtls_mpi *mpi) { for (size_t i = mpi->MBEDTLS_PRIVATE(n); i > 0; i--) { @@ -262,6 +188,82 @@ cleanup: #if defined(MBEDTLS_MPI_EXP_MOD_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) +#if defined (CONFIG_MBEDTLS_MPI_USE_INTERRUPT) + +static IRAM_ATTR void esp_mpi_complete_isr(void *arg) +{ + BaseType_t higher_woken; + mpi_hal_clear_interrupt(); + + xSemaphoreGiveFromISR(op_complete_sem, &higher_woken); + if (higher_woken) { + portYIELD_FROM_ISR(); + } +} + +static esp_err_t esp_mpi_isr_initialise(void) +{ + mpi_hal_clear_interrupt(); + mpi_hal_interrupt_enable(true); + if (op_complete_sem == NULL) { + static StaticSemaphore_t op_sem_buf; + op_complete_sem = xSemaphoreCreateBinaryStatic(&op_sem_buf); + if (op_complete_sem == NULL) { + ESP_LOGE(TAG, "Failed to create intr semaphore"); + return ESP_FAIL; + } + + const int isr_flags = esp_intr_level_to_flags(CONFIG_MBEDTLS_MPI_INTERRUPT_LEVEL); + + esp_err_t ret; + ret = esp_intr_alloc(ETS_RSA_INTR_SOURCE, isr_flags, esp_mpi_complete_isr, NULL, NULL); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to allocate RSA interrupt %d", ret); + + // This should be treated as fatal error as this API would mostly + // be invoked within mbedTLS interface. There is no way for the system + // to proceed if the MPI interrupt allocation fails here. + abort(); + } + } + + /* MPI is clocked proportionally to CPU clock, take power management lock */ +#ifdef CONFIG_PM_ENABLE + if (s_pm_cpu_lock == NULL) { + if (esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "mpi_sleep", &s_pm_sleep_lock) != ESP_OK) { + ESP_LOGE(TAG, "Failed to create PM sleep lock"); + return ESP_FAIL; + } + if (esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "mpi_cpu", &s_pm_cpu_lock) != ESP_OK) { + ESP_LOGE(TAG, "Failed to create PM CPU lock"); + return ESP_FAIL; + } + } + esp_pm_lock_acquire(s_pm_cpu_lock); + esp_pm_lock_acquire(s_pm_sleep_lock); +#endif + + return ESP_OK; +} + +static int esp_mpi_wait_intr(void) +{ + if (!xSemaphoreTake(op_complete_sem, 2000 / portTICK_PERIOD_MS)) { + ESP_LOGE("MPI", "Timed out waiting for completion of MPI Interrupt"); + return -1; + } + +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_release(s_pm_cpu_lock); + esp_pm_lock_release(s_pm_sleep_lock); +#endif // CONFIG_PM_ENABLE + + mpi_hal_interrupt_enable(false); + + return 0; +} +#endif // CONFIG_MBEDTLS_MPI_USE_INTERRUPT + #ifdef ESP_MPI_USE_MONT_EXP /* * Return the most significant one-bit. @@ -452,8 +454,6 @@ cleanup: return ret; } -#endif /* (MBEDTLS_MPI_EXP_MOD_ALT || MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) */ - /* * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) */ @@ -463,7 +463,6 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, { int ret; #if defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) - /* Try hardware API first and then fallback to software */ ret = esp_mpi_exp_mod( X, A, E, N, _RR ); if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) { ret = mbedtls_mpi_exp_mod_soft( X, A, E, N, _RR ); @@ -478,6 +477,8 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, return ret; } +#endif /* (MBEDTLS_MPI_EXP_MOD_ALT || MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) */ + #if defined(MBEDTLS_MPI_MUL_MPI_ALT) /* MBEDTLS_MPI_MUL_MPI_ALT */ static int mpi_mult_mpi_failover_mod_mult( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t z_words); @@ -493,7 +494,6 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi size_t y_words = bits_to_words(y_bits); size_t z_words = bits_to_words(x_bits + y_bits); size_t hw_words = mpi_hal_calc_hardware_words(MAX(x_words, y_words)); // length of one operand in hardware - /* Short-circuit eval if either argument is 0 or 1. This is needed as the mpi modular division diff --git a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c index c2aff10532d..c101f4e30c2 100644 --- a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c +++ b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c @@ -523,15 +523,6 @@ size_t esp_mbedtls_get_crt_size(mbedtls_x509_crt *cert, size_t *num) } #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA -void esp_mbedtls_free_dhm(mbedtls_ssl_context *ssl) -{ -#ifdef CONFIG_MBEDTLS_DHM_C - const mbedtls_ssl_config *conf = mbedtls_ssl_context_get_config(ssl); - mbedtls_mpi_free((mbedtls_mpi *)&conf->MBEDTLS_PRIVATE(dhm_P)); - mbedtls_mpi_free((mbedtls_mpi *)&conf->MBEDTLS_PRIVATE(dhm_G)); -#endif /* CONFIG_MBEDTLS_DHM_C */ -} - void esp_mbedtls_free_keycert(mbedtls_ssl_context *ssl) { mbedtls_ssl_config *conf = (mbedtls_ssl_config * )mbedtls_ssl_context_get_config(ssl); diff --git a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h index 54409766f53..ce52f05d5f3 100644 --- a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h +++ b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h @@ -88,8 +88,6 @@ int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl); size_t esp_mbedtls_get_crt_size(mbedtls_x509_crt *cert, size_t *num); #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA -void esp_mbedtls_free_dhm(mbedtls_ssl_context *ssl); - void esp_mbedtls_free_keycert(mbedtls_ssl_context *ssl); void esp_mbedtls_free_keycert_cert(mbedtls_ssl_context *ssl); diff --git a/components/mbedtls/port/dynamic/esp_ssl_cli.c b/components/mbedtls/port/dynamic/esp_ssl_cli.c index 376f104780e..f7aacca85e7 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_cli.c +++ b/components/mbedtls/port/dynamic/esp_ssl_cli.c @@ -153,7 +153,6 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); } else { #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA - esp_mbedtls_free_dhm(ssl); esp_mbedtls_free_keycert_key(ssl); esp_mbedtls_free_keycert(ssl); #endif diff --git a/components/mbedtls/port/dynamic/esp_ssl_srv.c b/components/mbedtls/port/dynamic/esp_ssl_srv.c index 5a657b56c71..d2000092268 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_srv.c +++ b/components/mbedtls/port/dynamic/esp_ssl_srv.c @@ -21,8 +21,7 @@ static bool ssl_ciphersuite_uses_rsa_key_ex(mbedtls_ssl_context *ssl) const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->MBEDTLS_PRIVATE(handshake)->ciphersuite_info; - if (ciphersuite_info->MBEDTLS_PRIVATE(key_exchange) == MBEDTLS_KEY_EXCHANGE_RSA || - ciphersuite_info->MBEDTLS_PRIVATE(key_exchange) == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { + if (ciphersuite_info->MBEDTLS_PRIVATE(key_exchange) == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA) { return true; } else { return false; @@ -101,7 +100,6 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); } else { #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA - esp_mbedtls_free_dhm(ssl); /** * Not free keycert->key and keycert until MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods. * For ssl server will use keycert->key to parse client key exchange. diff --git a/components/mbedtls/port/dynamic/esp_ssl_tls.c b/components/mbedtls/port/dynamic/esp_ssl_tls.c index 04f9ce10539..7036e66913a 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_tls.c +++ b/components/mbedtls/port/dynamic/esp_ssl_tls.c @@ -47,52 +47,48 @@ static int ssl_update_checksum_start( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; -#if defined(MBEDTLS_SHA256_C) - ret = mbedtls_md_update( &ssl->handshake->fin_sha256, buf, len ); + psa_status_t status; +#if defined(PSA_WANT_ALG_SHA_256) + status = psa_hash_update( + &ssl->handshake->fin_sha256_psa, buf, len); + if (status != PSA_SUCCESS) { + ret = psa_status_to_mbedtls(status, psa_to_md_errors, ARRAY_LENGTH(psa_to_md_errors), psa_generic_status_to_mbedtls); + return ret; + } #endif -#if defined(MBEDTLS_SHA512_C) - ret = mbedtls_md_update( &ssl->handshake->fin_sha384, buf, len ); +#if defined(PSA_WANT_ALG_SHA_384) + status = psa_hash_update( + &ssl->handshake->fin_sha384_psa, buf, len); + if (status != PSA_SUCCESS) { + ret = psa_status_to_mbedtls(status, psa_to_md_errors, ARRAY_LENGTH(psa_to_md_errors), psa_generic_status_to_mbedtls); + return ret; + } #endif - return ret; + return 0; } static int ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) { memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) ); - -#if defined(MBEDTLS_SHA256_C) - mbedtls_md_init( &handshake->fin_sha256 ); - int ret = mbedtls_md_setup( &handshake->fin_sha256, - mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), - 0 ); - if (ret != 0) { - return ret; - } - ret = mbedtls_md_starts( &handshake->fin_sha256 ); - if (ret != 0) { - return ret; + psa_status_t status; +#if defined(PSA_WANT_ALG_SHA_256) + handshake->fin_sha256_psa = psa_hash_operation_init(); + status = psa_hash_setup( &handshake->fin_sha256_psa, PSA_ALG_SHA_256 ); + if (status != PSA_SUCCESS) { + return psa_status_to_mbedtls(status, psa_to_md_errors, ARRAY_LENGTH(psa_to_md_errors), psa_generic_status_to_mbedtls); } #endif -#if defined(MBEDTLS_SHA512_C) - mbedtls_md_init( &handshake->fin_sha384 ); - ret = mbedtls_md_setup( &handshake->fin_sha384, - mbedtls_md_info_from_type(MBEDTLS_MD_SHA384), - 0 ); - if (ret != 0) { - return ret; - } - ret = mbedtls_md_starts( &handshake->fin_sha384 ); - if (ret != 0) { - return ret; +#if defined(PSA_WANT_ALG_SHA_384) + handshake->fin_sha384_psa = psa_hash_operation_init(); + status = psa_hash_setup( &handshake->fin_sha384_psa, PSA_ALG_SHA_384 ); + if (status != PSA_SUCCESS) { + return psa_status_to_mbedtls(status, psa_to_md_errors, ARRAY_LENGTH(psa_to_md_errors), psa_generic_status_to_mbedtls); } #endif handshake->update_checksum = ssl_update_checksum_start; -#if defined(MBEDTLS_DHM_C) - mbedtls_dhm_init( &handshake->dhm_ctx ); -#endif -#if defined(MBEDTLS_ECDH_C) && \ +#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) mbedtls_ecdh_init( &handshake->ecdh_ctx ); #endif diff --git a/components/mbedtls/port/ecc/ecc_alt.c b/components/mbedtls/port/ecc/ecc_alt.c index 7b70da59cfd..b9bae3204d0 100644 --- a/components/mbedtls/port/ecc/ecc_alt.c +++ b/components/mbedtls/port/ecc/ecc_alt.c @@ -9,8 +9,10 @@ #include "ecc_impl.h" #include "hal/ecc_ll.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "mbedtls/ecp.h" #include "mbedtls/platform_util.h" +#include "mbedtls/bignum.h" #if defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index 1385a7d8c1b..aedebbbc3ad 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -9,17 +9,23 @@ #include "esp_log.h" #include "hal/ecdsa_types.h" -#include "ecdsa/ecdsa_alt.h" + #include "soc/soc_caps.h" #include "esp_crypto_lock.h" #include "esp_crypto_periph_clk.h" -#include "mbedtls/error.h" -#include "mbedtls/ecdsa.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include "mbedtls/private/ecdsa.h" +#include "mbedtls/private/pk_private.h" #include "mbedtls/asn1.h" #include "mbedtls/asn1write.h" #include "mbedtls/platform_util.h" +#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 @@ -83,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 @@ -382,11 +428,29 @@ 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; } - keypair = mbedtls_pk_ec(*key_ctx); + + /* In mbedtls v4.0, MBEDTLS_PK_ECDSA doesn't allocate pk_ctx (ctx_alloc_func = NULL) + * because EC keys are managed through PSA. For hardware ECDSA, we need to manually + * allocate an mbedtls_ecp_keypair structure to store the magic values. */ + keypair = calloc(1, sizeof(mbedtls_ecp_keypair)); + if (keypair == NULL) { + return MBEDTLS_ERR_ECP_ALLOC_FAILED; + } + + /* Initialize the keypair structure */ + mbedtls_ecp_keypair_init(keypair); + + /* Manually assign to pk_ctx since mbedtls_pk_setup didn't do it */ + key_ctx->MBEDTLS_PRIVATE(pk_ctx) = keypair; return esp_ecdsa_privkey_load_mpi(&(keypair->MBEDTLS_PRIVATE(d)), efuse_blk); } @@ -429,7 +493,6 @@ int esp_ecdsa_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *c return 0; } - static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s, const mbedtls_mpi *d, const unsigned char* msg, size_t msg_len, ecdsa_sign_type_t k_type) @@ -544,7 +607,213 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s return 0; } +#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN */ + +void esp_ecdsa_free_pk_context(mbedtls_pk_context *key_ctx) +{ + if (key_ctx == NULL) { + return; + } + + /* In mbedtls v4.0, we manually allocated the keypair structure for hardware ECDSA. + * We need to free it manually since ctx_free_func is NULL for MBEDTLS_PK_ECDSA. */ + mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*key_ctx); + if (keypair != NULL) { + mbedtls_ecp_keypair_free(keypair); + free(keypair); + key_ctx->MBEDTLS_PRIVATE(pk_ctx) = NULL; + } + + 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 @@ -616,7 +885,15 @@ int esp_ecdsa_tee_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_ ESP_LOGE(TAG, "Failed to setup pk context, mbedtls_pk_setup() returned %d", ret); return ret; } - keypair = mbedtls_pk_ec(*key_ctx); + keypair = calloc(1, sizeof(mbedtls_ecp_keypair)); + if (keypair == NULL) { + ESP_LOGE(TAG, "Failed to allocate memory for ecp_keypair"); + return MBEDTLS_ERR_ECP_ALLOC_FAILED; + } + + mbedtls_ecp_keypair_init(keypair); + + key_ctx->MBEDTLS_PRIVATE(pk_ctx) = keypair; mbedtls_mpi_init(&(keypair->MBEDTLS_PRIVATE(d))); keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) = ECDSA_KEY_MAGIC_TEE; @@ -693,8 +970,8 @@ static int esp_ecdsa_tee_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mp return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } - mbedtls_mpi_read_binary(r, sign.sign_r, len); - mbedtls_mpi_read_binary(s, sign.sign_s, len); + mbedtls_mpi_read_binary(r, sign.signature, len); + mbedtls_mpi_read_binary(s, sign.signature + len, len); return 0; } @@ -906,7 +1183,7 @@ static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, unsigned char *sig, size_t sig_size, size_t *slen) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + int ret = PSA_ERROR_CORRUPTION_DETECTED; unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 }; // Setting the pointer p to the end of the buffer as the functions used afterwards write in backwards manner in the given buffer. unsigned char *p = buf + sizeof(buf); @@ -944,7 +1221,7 @@ int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, return __real_mbedtls_ecdsa_write_signature_restartable(ctx, md_alg, hash, hlen, sig, sig_size, slen, f_rng, p_rng, rs_ctx); } - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + int ret = PSA_ERROR_CORRUPTION_DETECTED; mbedtls_mpi r, s; mbedtls_mpi_init(&r); @@ -1155,7 +1432,7 @@ int __wrap_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, const unsigned char *sig, size_t slen, mbedtls_ecdsa_restart_ctx *rs_ctx) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + int ret = PSA_ERROR_CORRUPTION_DETECTED; unsigned char *p = (unsigned char *) sig; const unsigned char *end = sig + slen; size_t len; @@ -1170,8 +1447,7 @@ int __wrap_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, } if (p + len != end) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; goto cleanup; } @@ -1190,7 +1466,7 @@ int __wrap_mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, * Return 0 if the buffer just contains the signature, and a specific * error code if the valid signature is followed by more data. */ if (p != end) { - ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; + ret = PSA_ERROR_INVALID_SIGNATURE; } cleanup: diff --git a/components/mbedtls/port/esp_ds/esp_ds_common.c b/components/mbedtls/port/esp_ds/esp_ds_common.c index f56f8bb0635..9dcaaba0043 100644 --- a/components/mbedtls/port/esp_ds/esp_ds_common.c +++ b/components/mbedtls/port/esp_ds/esp_ds_common.c @@ -12,7 +12,7 @@ #include "esp_ds/esp_ds_rsa.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "mbedtls/rsa.h" +#include "psa/crypto.h" #ifdef SOC_DIG_SIGN_SUPPORTED #include "rom/digital_signature.h" @@ -49,6 +49,16 @@ size_t esp_ds_get_keylen(void *ctx) return ((s_ds_data->rsa_length + 1) * FACTOR_KEYLEN_IN_BYTES); } +size_t esp_ds_get_keylen_alt(mbedtls_pk_context *ctx) +{ + if (s_ds_data == NULL) { + ESP_LOGE(TAG, "s_ds_data is NULL, cannot get key length"); + return 0; + } + /* calculating the rsa_length in bytes */ + return ((s_ds_data->rsa_length + 1) * FACTOR_KEYLEN_IN_BYTES); +} + /* Lock for the DS session, other TLS connections trying to use the DS peripheral will be blocked * till this DS session is completed (i.e. TLS handshake for this connection is completed) */ static void __attribute__((constructor)) esp_ds_conn_lock(void) @@ -134,7 +144,7 @@ int esp_ds_mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src, mbedtls_md_init(&md_ctx); md_info = mbedtls_md_info_from_type(md_alg); if (md_info == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) { @@ -191,11 +201,11 @@ int esp_ds_hash_mprime(const unsigned char *hash, size_t hlen, const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; mbedtls_md_context_t md_ctx; - int ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + int ret = PSA_ERROR_INVALID_ARGUMENT; const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg); if (md_info == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } mbedtls_md_init(&md_ctx); diff --git a/components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c b/components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c index 9ef5071a758..55b60497a39 100644 --- a/components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c +++ b/components/mbedtls/port/esp_ds/esp_rsa_dec_alt.c @@ -9,7 +9,8 @@ #include "sdkconfig.h" #include "esp_ds.h" #include "rsa_dec_alt.h" -#include "mbedtls/rsa.h" +#include "mbedtls/private/rsa.h" +#include "psa/crypto.h" #include "esp_ds_common.h" #include "esp_log.h" @@ -24,7 +25,7 @@ static int esp_ds_rsaes_pkcs1_v15_unpadding(unsigned char *input, size_t *olen) { if (ilen < MIN_V15_PADDING_LEN) { - return MBEDTLS_ERR_RSA_INVALID_PADDING; + return MBEDTLS_ERR_CIPHER_INVALID_PADDING; } unsigned char bad = 0; @@ -39,7 +40,7 @@ static int esp_ds_rsaes_pkcs1_v15_unpadding(unsigned char *input, bad |= input[0]; /* Check the padding type */ - bad |= input[1] ^ MBEDTLS_RSA_CRYPT; + bad |= input[1] ^ 2; // MBEDTLS_RSA_CRYPT; /* Scan for separator (0x00) and count padding bytes in constant time */ for (size_t i = 2; i < ilen; i++) { @@ -72,7 +73,7 @@ static int esp_ds_rsaes_pkcs1_v15_unpadding(unsigned char *input, } if (bad) { - return MBEDTLS_ERR_RSA_INVALID_PADDING; + return PSA_ERROR_INVALID_ARGUMENT; } *olen = msg_len; @@ -88,7 +89,7 @@ static int esp_ds_compute_hash(mbedtls_md_type_t md_alg, { const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg); if (md_info == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } return mbedtls_md(md_info, input, ilen, output); } @@ -165,7 +166,7 @@ static int esp_ds_rsaes_pkcs1_v21_unpadding(unsigned char *input, bad |= (output_max_len < msg_len); if (bad) { - return MBEDTLS_ERR_RSA_INVALID_PADDING; + return PSA_ERROR_INVALID_ARGUMENT; } /* Copy message in constant time */ @@ -181,7 +182,7 @@ int esp_ds_rsa_decrypt(void *ctx, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len) { - int padding = MBEDTLS_RSA_PKCS_V15; + int padding = MBEDTLS_PK_RSA_PKCS_V15; if (ctx != NULL) { mbedtls_rsa_context *rsa_ctx = (mbedtls_rsa_context *)ctx; @@ -256,12 +257,12 @@ int esp_ds_rsa_decrypt(void *ctx, size_t *olen, } // Unpad the decrypted data - if (padding == MBEDTLS_RSA_PKCS_V15) { + if (padding == MBEDTLS_PK_RSA_PKCS_V15) { if (esp_ds_rsaes_pkcs1_v15_unpadding((uint8_t *)output_tmp, ilen, (uint8_t *)output_tmp, ilen, olen) != 0) { ESP_LOGE(TAG, "Error in v15 unpadding"); goto exit; } - } else if (padding == MBEDTLS_RSA_PKCS_V21) { + } else if (padding == MBEDTLS_PK_RSA_PKCS_V21) { if (esp_ds_rsaes_pkcs1_v21_unpadding((uint8_t *)output_tmp, ilen, (uint8_t *)output_tmp, ilen, olen) != 0) { ESP_LOGE(TAG, "Error in v21 unpadding"); goto exit; diff --git a/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c b/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c index a595e8f3b76..ff273287d7f 100644 --- a/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c +++ b/components/mbedtls/port/esp_ds/esp_rsa_sign_alt.c @@ -14,14 +14,74 @@ #include "esp_heap_caps.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "mbedtls/build_info.h" -#include "mbedtls/rsa.h" -#include "mbedtls/oid.h" +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" +#include "mbedtls/private/rsa.h" +#include "mbedtls/pk.h" #include "mbedtls/platform_util.h" +#include "mbedtls/asn1.h" +#include "mbedtls/md.h" #include static const char *TAG = "ESP_RSA_SIGN_ALT"; +/* + * Local OID lookup table for hash algorithms + * This replicates the OID data needed for PKCS#1 v1.5 DigestInfo encoding + * Since OID access has moved to internal driver headers in PSA transition, + * we maintain this local table for the hardware accelerator implementation. + */ +typedef struct { + mbedtls_md_type_t md_alg; + const char *oid; + size_t oid_len; +} oid_md_mapping_t; + +static const oid_md_mapping_t oid_md_table[] = { +#if defined(PSA_WANT_ALG_MD5) + { MBEDTLS_MD_MD5, "\x2a\x86\x48\x86\xf7\x0d\x02\x05", 8 }, +#endif +#if defined(PSA_WANT_ALG_SHA_1) + { MBEDTLS_MD_SHA1, "\x2b\x0e\x03\x02\x1a", 5 }, +#endif +#if defined(PSA_WANT_ALG_SHA_224) + { MBEDTLS_MD_SHA224, "\x60\x86\x48\x01\x65\x03\x04\x02\x04", 9 }, +#endif +#if defined(PSA_WANT_ALG_SHA_256) + { MBEDTLS_MD_SHA256, "\x60\x86\x48\x01\x65\x03\x04\x02\x01", 9 }, +#endif +#if defined(PSA_WANT_ALG_SHA_384) + { MBEDTLS_MD_SHA384, "\x60\x86\x48\x01\x65\x03\x04\x02\x02", 9 }, +#endif +#if defined(PSA_WANT_ALG_SHA_512) + { MBEDTLS_MD_SHA512, "\x60\x86\x48\x01\x65\x03\x04\x02\x03", 9 }, +#endif +#if defined(PSA_WANT_ALG_RIPEMD160) + { MBEDTLS_MD_RIPEMD160, "\x2b\x24\x03\x02\x01", 5 }, +#endif + { MBEDTLS_MD_NONE, NULL, 0 } +}; + +/** + * @brief Get OID for hash algorithm (local implementation) + * + * @param md_alg Hash algorithm type + * @param oid Output pointer for OID string + * @param olen Output pointer for OID length + * @return 0 on success, PSA_ERROR_NOT_SUPPORTED if not found + */ +static int esp_ds_get_oid_by_md(mbedtls_md_type_t md_alg, const char **oid, size_t *olen) +{ + for (size_t i = 0; oid_md_table[i].md_alg != MBEDTLS_MD_NONE; i++) { + if (oid_md_table[i].md_alg == md_alg) { + *oid = oid_md_table[i].oid; + *olen = oid_md_table[i].oid_len; + return 0; + } + } + return PSA_ERROR_NOT_SUPPORTED; +} + static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, @@ -37,11 +97,11 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, if ( md_alg != MBEDTLS_MD_NONE ) { const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); if ( md_info == NULL ) { - return ( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } - if ( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) { - return ( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + if ( esp_ds_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) { + return ( PSA_ERROR_INVALID_ARGUMENT ); } hashlen = mbedtls_md_get_size( md_info ); @@ -51,7 +111,7 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, if ( 8 + hashlen + oid_size >= 0x80 || 10 + hashlen < hashlen || 10 + hashlen + oid_size < 10 + hashlen ) { - return ( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } /* @@ -63,12 +123,12 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, * - Need oid_size bytes for hash alg OID. */ if ( nb_pad < 10 + hashlen + oid_size ) { - return ( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } nb_pad -= 10 + hashlen + oid_size; } else { if ( nb_pad < hashlen ) { - return ( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } nb_pad -= hashlen; @@ -77,7 +137,7 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, /* Need space for signature header and padding delimiter (3 bytes), * and 8 bytes for the minimal padding */ if ( nb_pad < 3 + 8 ) { - return ( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } nb_pad -= 3; @@ -86,7 +146,7 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, /* Write signature header and padding */ *p++ = 0; - *p++ = MBEDTLS_RSA_SIGN; + *p++ = 1; //MBEDTLS_RSA_SIGN; memset( p, 0xFF, nb_pad ); p += nb_pad; *p++ = 0; @@ -129,7 +189,7 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, * after the initial bounds check. */ if ( p != dst + dst_len ) { mbedtls_platform_zeroize( dst, dst_len ); - return ( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + return ( PSA_ERROR_INVALID_ARGUMENT ); } return ( 0 ); @@ -147,15 +207,15 @@ static int rsa_rsassa_pss_pkcs1_v21_encode( int (*f_rng)(void *, unsigned char * unsigned char *p = sig; unsigned char *salt = NULL; size_t slen, min_slen, hlen, offset = 0; - int ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + int ret = PSA_ERROR_INVALID_ARGUMENT; size_t msb; if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } if (f_rng == NULL) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } olen = dst_len; @@ -164,20 +224,20 @@ static int rsa_rsassa_pss_pkcs1_v21_encode( int (*f_rng)(void *, unsigned char * /* Gather length of hash to sign */ size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg); if (exp_hashlen == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } if (hashlen != exp_hashlen) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } } hlen = mbedtls_md_get_size_from_type(md_alg); if (hlen == 0) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } - if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY) { + if (saltlen == -1) { /* Calculate the largest possible salt length, up to the hash size. * Normally this is the hash length, which is the maximum salt length * according to FIPS 185-4 �5.5 (e) and common practice. If there is not @@ -187,14 +247,14 @@ static int rsa_rsassa_pss_pkcs1_v21_encode( int (*f_rng)(void *, unsigned char * * (PKCS#1 v2.2) �9.1.1 step 3. */ min_slen = hlen - 2; if (olen < hlen + min_slen + 2) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } else if (olen >= hlen + hlen + 2) { slen = hlen; } else { slen = olen - hlen - 2; } } else if ((saltlen < 0) || (saltlen + hlen + 2 > olen)) { - return MBEDTLS_ERR_RSA_BAD_INPUT_DATA; + return PSA_ERROR_INVALID_ARGUMENT; } else { slen = (size_t) saltlen; } @@ -210,7 +270,7 @@ static int rsa_rsassa_pss_pkcs1_v21_encode( int (*f_rng)(void *, unsigned char * /* Generate salt of length slen in place in the encoded message */ salt = p; if ((ret = f_rng(p_rng, salt, slen)) != 0) { - return MBEDTLS_ERR_RSA_RNG_FAILED; + return PSA_ERROR_INVALID_ARGUMENT; } p += slen; @@ -246,7 +306,7 @@ static int rsa_rsassa_pkcs1_v21_encode(int (*f_rng)(void *, unsigned char *, siz size_t dst_len, unsigned char *dst ) { - return rsa_rsassa_pss_pkcs1_v21_encode(f_rng, p_rng, md_alg, hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, dst, dst_len); + return rsa_rsassa_pss_pkcs1_v21_encode(f_rng, p_rng, md_alg, hashlen, hash, -1, dst, dst_len); } #endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ @@ -254,6 +314,15 @@ int esp_ds_rsa_sign( void *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ) +{ + mbedtls_pk_context *pk = (mbedtls_pk_context *)ctx; + size_t sig_len = 0; + return esp_ds_rsa_sign_alt(pk, md_alg, hash, hashlen, sig, 0, &sig_len); +} + +int esp_ds_rsa_sign_alt(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) { esp_ds_context_t *esp_ds_ctx = NULL; esp_err_t ds_r; @@ -263,7 +332,11 @@ int esp_ds_rsa_sign( void *ctx, * which allows NULL ctx. If ctx is NULL, then the default padding * MBEDTLS_RSA_PKCS_V15 is used. */ - int padding = MBEDTLS_RSA_PKCS_V15; + int padding = MBEDTLS_PK_RSA_PKCS_V15; + void *ctx = NULL; + if (pk != NULL) { + ctx = pk->MBEDTLS_PRIVATE(pk_ctx); + } if (ctx != NULL) { mbedtls_rsa_context *rsa_ctx = (mbedtls_rsa_context *)ctx; padding = rsa_ctx->MBEDTLS_PRIVATE(padding); @@ -274,11 +347,11 @@ int esp_ds_rsa_sign( void *ctx, return -1; } const size_t data_len = s_ds_data->rsa_length + 1; - const size_t sig_len = data_len * FACTOR_KEYLEN_IN_BYTES; + const size_t _sig_len = data_len * FACTOR_KEYLEN_IN_BYTES; - if (padding == MBEDTLS_RSA_PKCS_V21) { + if (padding == MBEDTLS_PK_RSA_PKCS_V21) { #ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - if ((ret = (rsa_rsassa_pkcs1_v21_encode(f_rng, p_rng ,md_alg, hashlen, hash, sig_len, sig ))) != 0) { + if ((ret = (rsa_rsassa_pkcs1_v21_encode(mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ,md_alg, hash_len, hash, _sig_len, sig ))) != 0) { ESP_LOGE(TAG, "Error in pkcs1_v21 encoding, returned %d", ret); return -1; } @@ -287,13 +360,13 @@ int esp_ds_rsa_sign( void *ctx, return -1; #endif /* CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 */ } else { - if ((ret = (rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash, sig_len, sig ))) != 0) { + if ((ret = (rsa_rsassa_pkcs1_v15_encode(md_alg, hash_len, hash, _sig_len, sig ))) != 0) { ESP_LOGE(TAG, "Error in pkcs1_v15 encoding, returned %d", ret); return -1; } } - uint32_t *signature = heap_caps_malloc_prefer(sig_len, 2, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + uint32_t *signature = heap_caps_malloc_prefer(_sig_len, 2, MALLOC_CAP_32BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); if (signature == NULL) { ESP_LOGE(TAG, "Could not allocate memory for internal DS operations"); return -1; @@ -330,5 +403,6 @@ int esp_ds_rsa_sign( void *ctx, ((uint32_t *)sig)[i] = SWAP_INT32(((uint32_t *)signature)[(data_len) - (i + 1)]); } heap_caps_free(signature); + *sig_len = _sig_len; return 0; } diff --git a/components/mbedtls/port/esp_hardware.c b/components/mbedtls/port/esp_hardware.c index 5633cccf3a6..db79471b2ec 100644 --- a/components/mbedtls/port/esp_hardware.c +++ b/components/mbedtls/port/esp_hardware.c @@ -1,21 +1,15 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include #include "esp_random.h" -#include "mbedtls/esp_mbedtls_random.h" - #include - -#ifndef MBEDTLS_ENTROPY_HARDWARE_ALT -#error "MBEDTLS_ENTROPY_HARDWARE_ALT should always be set in ESP-IDF" -#endif +#include "psa/crypto.h" int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ) @@ -25,9 +19,16 @@ int mbedtls_hardware_poll( void *data, return 0; } -int mbedtls_esp_random(void *ctx, unsigned char *buf, size_t len) +#if defined(MBEDTLS_PSA_DRIVER_GET_ENTROPY) +psa_status_t mbedtls_psa_external_get_random( + mbedtls_psa_external_random_context_t *context, + uint8_t *output, size_t output_size, size_t *output_length) { - (void) ctx; // unused - esp_fill_random(buf, len); - return 0; + if (context == NULL || output == NULL || output_length == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + esp_fill_random(output, output_size); + *output_length = output_size; + return PSA_SUCCESS; } +#endif // MBEDTLS_PSA_DRIVER_GET_ENTROPY diff --git a/components/mbedtls/port/esp_psa_crypto_init.c b/components/mbedtls/port/esp_psa_crypto_init.c new file mode 100644 index 00000000000..a929c82356c --- /dev/null +++ b/components/mbedtls/port/esp_psa_crypto_init.c @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/startup_internal.h" +#include "psa/crypto.h" +#include "esp_err.h" +#include "esp_log.h" +#include "sdkconfig.h" + +void mbedtls_psa_crypto_init_include_impl(void); + +/** + * @brief Initialize PSA Crypto library at system startup + * + * This function is called during the SECONDARY initialization stage with priority 104, + * which ensures it runs after esp_security_init (priority 103). This ordering guarantees + * that hardware crypto support is fully initialized before PSA crypto initialization. + */ +ESP_SYSTEM_INIT_FN(mbedtls_psa_crypto_init_fn, SECONDARY, BIT(0), 104) +{ + psa_status_t status = psa_crypto_init(); + if (status != PSA_SUCCESS) { + return ESP_FAIL; + } + return ESP_OK; +} + +void mbedtls_psa_crypto_init_include_impl(void) +{ + // Linker hook, exists for no other purpose +} diff --git a/components/mbedtls/port/esp_timing.c b/components/mbedtls/port/esp_timing.c index 96858f765ac..f461af36162 100644 --- a/components/mbedtls/port/esp_timing.c +++ b/components/mbedtls/port/esp_timing.c @@ -14,7 +14,6 @@ * DTLS (in particular mbedtls_ssl_set_timer_cb() must be called for DTLS * which requires these 2 delay functions). */ - #include #if !defined(MBEDTLS_ESP_TIMING_C) diff --git a/components/mbedtls/port/include/aes/esp_aes_gcm.h b/components/mbedtls/port/include/aes/esp_aes_gcm.h index c270c9f97b8..dd89f39205b 100644 --- a/components/mbedtls/port/include/aes/esp_aes_gcm.h +++ b/components/mbedtls/port/include/aes/esp_aes_gcm.h @@ -11,7 +11,6 @@ #pragma once #include "aes/esp_aes.h" -#include "mbedtls/cipher.h" #ifdef __cplusplus extern "C" { @@ -69,7 +68,7 @@ void esp_aes_gcm_init( esp_gcm_context *ctx); * \return A cipher-specific error code on failure. */ int esp_aes_gcm_setkey( esp_gcm_context *ctx, - mbedtls_cipher_id_t cipher, + int cipher, const unsigned char *key, unsigned int keybits ); diff --git a/components/mbedtls/port/include/ecdsa/ecdsa_alt.h b/components/mbedtls/port/include/ecdsa/ecdsa_alt.h index 3fe1145b2dc..58ca85713e0 100644 --- a/components/mbedtls/port/include/ecdsa/ecdsa_alt.h +++ b/components/mbedtls/port/include/ecdsa/ecdsa_alt.h @@ -110,6 +110,20 @@ int esp_ecdsa_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *c #endif // CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || __DOXYGEN__ +/** + * @brief Free the PK context initialized with hardware ECDSA key. + * This function properly cleans up the manually allocated mbedtls_ecp_keypair + * structure and then frees the PK context. + * + * Note: In mbedtls v4.0, ECDSA keys are managed through PSA, so the standard + * mbedtls_pk_free() does not deallocate the manually created keypair structure. + * Always use this function instead of mbedtls_pk_free() for contexts initialized + * with esp_ecdsa_set_pk_context(). + * + * @param key_ctx The PK context to free (initialized with esp_ecdsa_set_pk_context) + */ +void esp_ecdsa_free_pk_context(mbedtls_pk_context *key_ctx); + #if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN || __DOXYGEN__ /** diff --git a/components/mbedtls/port/include/entropy_poll.h b/components/mbedtls/port/include/entropy_poll.h index 4bae4d1db3e..3bdaf8357fc 100644 --- a/components/mbedtls/port/include/entropy_poll.h +++ b/components/mbedtls/port/include/entropy_poll.h @@ -6,7 +6,6 @@ */ #ifndef MBEDTLS_ENTROPY_POLL_H #define MBEDTLS_ENTROPY_POLL_H -#include "mbedtls/build_info.h" #include #ifdef __cplusplus extern "C" { diff --git a/components/mbedtls/port/include/esp_ds/esp_ds_rsa.h b/components/mbedtls/port/include/esp_ds/esp_ds_rsa.h index 7f126d546b3..d33875bd622 100644 --- a/components/mbedtls/port/include/esp_ds/esp_ds_rsa.h +++ b/components/mbedtls/port/include/esp_ds/esp_ds_rsa.h @@ -12,7 +12,7 @@ extern "C" { #include "esp_ds.h" #include "mbedtls/md.h" - +#include "mbedtls/pk.h" /** * @brief ESP-DS data context * @@ -68,6 +68,30 @@ int esp_ds_rsa_sign( void *ctx, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ); +/** + * @brief Alternate implementation for mbedtls_pk_sign, uses DS module for hardware accelerated RSA sign operation + * + * This function is an alternate implementation compatible with mbedtls_pk_sign interface. + * It internally makes use of the DS (Digital Signature) peripheral to perform hardware + * accelerated RSA signature operations. + * + * @param pk Pointer to the mbedtls_pk_context structure containing the public key context + * @param md_alg Message digest algorithm type used for hashing (e.g., MBEDTLS_MD_SHA256) + * @param hash Pointer to the hash value to be signed + * @param hash_len Length of the hash value in bytes + * @param sig Buffer to hold the generated signature + * @param sig_size Maximum size of the signature buffer in bytes + * @param sig_len Pointer to store the actual length of the generated signature in bytes + * + * @return + * - 0 on success + * - MBEDTLS_ERR_PK_BAD_INPUT_DATA if input parameters are invalid + * - MBEDTLS_ERR_PK_ALLOC_FAILED if memory allocation fails + * - Other mbedtls error codes on failure + */ +int esp_ds_rsa_sign_alt(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); /* * @brief Get RSA key length in bytes from internal DS context * @@ -75,6 +99,18 @@ int esp_ds_rsa_sign( void *ctx, */ size_t esp_ds_get_keylen(void *ctx); +/** + * @brief Get RSA key length in bytes from mbedtls_pk_context + * + * This function retrieves the RSA key length from an mbedtls_pk_context structure. + * It is an alternate implementation compatible with mbedtls PK interface. + * + * @param ctx Pointer to the mbedtls_pk_context structure + * + * @return RSA key length in bytes, or 0 if the context is invalid + */ +size_t esp_ds_get_keylen_alt(mbedtls_pk_context *ctx); + /* * @brief Set timeout (equal to TLS session timeout), so that DS module usage can be synchronized in case of multiple TLS connections using DS module, */ diff --git a/components/mbedtls/port/include/mbedtls/bignum.h b/components/mbedtls/port/include/mbedtls/bignum.h index 4f84bed7407..6867fbb7610 100644 --- a/components/mbedtls/port/include/mbedtls/bignum.h +++ b/components/mbedtls/port/include/mbedtls/bignum.h @@ -5,7 +5,8 @@ */ #pragma once -#include_next "mbedtls/bignum.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include_next "mbedtls/private/bignum.h" #include "sdkconfig.h" /** diff --git a/components/mbedtls/port/include/mbedtls/ecp.h b/components/mbedtls/port/include/mbedtls/ecp.h index 28ccd5c79ce..3e8733e95a4 100644 --- a/components/mbedtls/port/include/mbedtls/ecp.h +++ b/components/mbedtls/port/include/mbedtls/ecp.h @@ -5,7 +5,8 @@ */ #pragma once -#include_next "mbedtls/ecp.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include_next "mbedtls/private/ecp.h" #include "sdkconfig.h" #ifdef __cplusplus diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 611d0878a80..8e5b5b2ec39 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -25,17 +25,49 @@ #ifndef ESP_CONFIG_H #define ESP_CONFIG_H +#define MBEDTLS_ALLOW_PRIVATE_ACCESS + #include "sdkconfig.h" +#if (defined(MBEDTLS_MAJOR_VERSION) && (MBEDTLS_MAJOR_VERSION < 4)) #include "mbedtls/mbedtls_config.h" +#endif // MBEDTLS_MAJOR_VERSION < 4 #include "soc/soc_caps.h" + +#ifndef CONFIG_IDF_TARGET_LINUX +#undef MBEDTLS_PSA_BUILTIN_GET_ENTROPY +#define MBEDTLS_PSA_DRIVER_GET_ENTROPY +#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG +#endif // !CONFIG_IDF_TARGET_LINUX + +/** + * \def MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS + * + * Assume all buffers passed to PSA functions are owned exclusively by the + * PSA function and are not stored in shared memory. + * + * This option may be enabled if all buffers passed to any PSA function reside + * in memory that is accessible only to the PSA function during its execution. + * + * This option MUST be disabled whenever buffer arguments are in memory shared + * with an untrusted party, for example where arguments to PSA calls are passed + * across a trust boundary. + * + * \note Enabling this option reduces memory usage and code size. + * + * \note Enabling this option causes overlap of input and output buffers + * not to be supported by PSA functions. + */ +#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS + +#define PSA_WANT_ECC_SECP_R1_192 1 + /** * \name SECTION: System support * * This section sets system specific settings. * \{ */ - /** * \def MBEDTLS_HAVE_TIME * @@ -130,6 +162,8 @@ /** Override calloc(), free() except for case where memory allocation scheme is not set to custom */ #ifndef CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC #include "esp_mem.h" +#undef MBEDTLS_PLATFORM_STD_CALLOC +#undef MBEDTLS_PLATFORM_STD_FREE #define MBEDTLS_PLATFORM_STD_CALLOC esp_mbedtls_mem_calloc #define MBEDTLS_PLATFORM_STD_FREE esp_mbedtls_mem_free #endif @@ -144,17 +178,7 @@ * \{ */ -/* The following units have ESP32 hardware support, - uncommenting each _ALT macro will use the - hardware-accelerated implementation. */ #ifdef CONFIG_MBEDTLS_HARDWARE_AES -#define MBEDTLS_AES_ALT -#else -#undef MBEDTLS_AES_ALT -#endif - -#ifdef CONFIG_MBEDTLS_HARDWARE_AES -#define MBEDTLS_GCM_ALT #ifdef CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER /* Prefer hardware and fallback to software */ #define MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK @@ -167,11 +191,14 @@ with software fallback. */ #ifdef CONFIG_MBEDTLS_HARDWARE_SHA -#define MBEDTLS_SHA1_ALT -#define MBEDTLS_SHA256_ALT - +#define MBEDTLS_PSA_ACCEL_ALG_SHA_1 +#define MBEDTLS_PSA_ACCEL_ALG_SHA_224 +#define MBEDTLS_PSA_ACCEL_ALG_SHA_256 +#if SOC_SHA_SUPPORT_SHA512 +#define MBEDTLS_PSA_ACCEL_ALG_SHA_384 +#define MBEDTLS_PSA_ACCEL_ALG_SHA_512 +#endif #if SOC_SHA_SUPPORT_SHA512 -#define MBEDTLS_SHA512_ALT #else #undef MBEDTLS_SHA512_ALT #endif @@ -185,11 +212,12 @@ /* MBEDTLS_MDx_ALT to enable ROM MD support with software fallback. */ -#ifdef CONFIG_MBEDTLS_ROM_MD5 -#define MBEDTLS_MD5_ALT -#else -#undef MBEDTLS_MD5_ALT -#endif +/* TODO: IDF-15029 */ +// #ifdef CONFIG_MBEDTLS_ROM_MD5 +// #define MBEDTLS_MD5_ALT +// #else +// #undef MBEDTLS_MD5_ALT +// #endif /* The following MPI (bignum) functions have hardware support. * Uncommenting these macros will use the hardware-accelerated @@ -199,6 +227,7 @@ #ifdef CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI /* Prefer hardware and fallback to software */ #define MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK + #define MBEDTLS_MPI_EXP_MOD_ALT #else /* Hardware only mode */ #define MBEDTLS_MPI_EXP_MOD_ALT @@ -238,21 +267,6 @@ #undef MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK #endif -#ifndef CONFIG_IDF_TARGET_LINUX -/** - * \def MBEDTLS_ENTROPY_HARDWARE_ALT - * - * Uncomment this macro to let mbed TLS use your own implementation of a - * hardware entropy collector. - * - * Your function must be called \c mbedtls_hardware_poll(), have the same - * prototype as declared in entropy_poll.h, and accept NULL as first argument. - * - * Uncomment to use your own hardware entropy collector. - */ -#define MBEDTLS_ENTROPY_HARDWARE_ALT -#endif // !CONFIG_IDF_TARGET_LINUX - /** * \def MBEDTLS_AES_ROM_TABLES * @@ -314,9 +328,11 @@ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. */ #ifdef CONFIG_MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_CIPHER_MODE_CBC +#define PSA_WANT_ALG_CBC_NO_PADDING 1 +#define PSA_WANT_ALG_CBC_PKCS7 1 #else -#undef MBEDTLS_CIPHER_MODE_CBC +#undef PSA_WANT_ALG_CBC_NO_PADDING +#undef PSA_WANT_ALG_CBC_PKCS7 #endif /** @@ -325,9 +341,9 @@ * Enable Cipher Feedback mode (CFB) for symmetric ciphers. */ #ifdef CONFIG_MBEDTLS_CIPHER_MODE_CFB -#define MBEDTLS_CIPHER_MODE_CFB +#define PSA_WANT_ALG_CFB 1 #else -#undef MBEDTLS_CIPHER_MODE_CFB +#undef PSA_WANT_ALG_CFB #endif /** @@ -336,9 +352,9 @@ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. */ #ifdef CONFIG_MBEDTLS_CIPHER_MODE_CTR -#define MBEDTLS_CIPHER_MODE_CTR +#define PSA_WANT_ALG_CTR 1 #else -#undef MBEDTLS_CIPHER_MODE_CTR +#undef PSA_WANT_ALG_CTR #endif /** * \def MBEDTLS_CIPHER_MODE_OFB @@ -346,9 +362,9 @@ * Enable Output Feedback mode (OFB) for symmetric ciphers. */ #ifdef CONFIG_MBEDTLS_CIPHER_MODE_OFB -#define MBEDTLS_CIPHER_MODE_OFB +#define PSA_WANT_ALG_OFB 1 #else -#undef MBEDTLS_CIPHER_MODE_OFB +#undef PSA_WANT_ALG_OFB #endif /** @@ -362,41 +378,6 @@ #undef MBEDTLS_CIPHER_MODE_XTS #endif -/** - * \def MBEDTLS_CIPHER_PADDING_PKCS7 - * - * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for - * specific padding modes in the cipher layer with cipher modes that support - * padding (e.g. CBC) - * - * If you disable all padding modes, only full blocks can be used with CBC. - * - * Enable padding modes in the cipher layer. - */ -#ifdef CONFIG_MBEDTLS_CIPHER_PADDING_PKCS7 -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#else -#undef MBEDTLS_CIPHER_PADDING_PKCS7 -#endif - -#ifdef CONFIG_MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#else -#undef MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#endif - -#ifdef CONFIG_MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#else -#undef MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#endif - -#ifdef CONFIG_MBEDTLS_CIPHER_PADDING_ZEROS -#define MBEDTLS_CIPHER_PADDING_ZEROS -#else -#undef MBEDTLS_CIPHER_PADDING_ZEROS -#endif - /** * \def MBEDTLS_ECP_RESTARTABLE * @@ -493,11 +474,11 @@ * * Module: library/cmac.c * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_DES_C + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C * */ #ifdef CONFIG_MBEDTLS_CMAC_C -#define MBEDTLS_CMAC_C +#define PSA_WANT_ALG_CMAC 1 #else #ifdef CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL /* The mbedtls present in ROM is built with the MBEDTLS_CMAC_C symbol being enabled, @@ -505,7 +486,7 @@ */ #error "CONFIG_MBEDTLS_CMAC_C cannot be disabled when CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL is enabled" #endif -#undef MBEDTLS_CMAC_C +#undef PSA_WANT_ALG_CMAC #endif /** @@ -517,16 +498,6 @@ * Comment macros to disable the curve and functions for it */ /* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ -#ifdef CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#else -#undef MBEDTLS_ECP_DP_SECP192R1_ENABLED -#endif -#ifdef CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#else -#undef MBEDTLS_ECP_DP_SECP224R1_ENABLED -#endif #ifdef CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED #define MBEDTLS_ECP_DP_SECP256R1_ENABLED #else @@ -536,22 +507,13 @@ #define MBEDTLS_ECP_DP_SECP384R1_ENABLED #else #undef MBEDTLS_ECP_DP_SECP384R1_ENABLED +#undef PSA_WANT_ECC_SECP_R1_384 #endif #ifdef CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED #define MBEDTLS_ECP_DP_SECP521R1_ENABLED #else #undef MBEDTLS_ECP_DP_SECP521R1_ENABLED #endif -#ifdef CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#else -#undef MBEDTLS_ECP_DP_SECP192K1_ENABLED -#endif -#ifdef CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#else -#undef MBEDTLS_ECP_DP_SECP224K1_ENABLED -#endif #ifdef CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED #define MBEDTLS_ECP_DP_SECP256K1_ENABLED #else @@ -623,9 +585,9 @@ * Comment this macro to disable deterministic ECDSA. */ #ifdef CONFIG_MBEDTLS_ECDSA_DETERMINISTIC -#define MBEDTLS_ECDSA_DETERMINISTIC +#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 #else -#undef MBEDTLS_ECDSA_DETERMINISTIC +#undef PSA_WANT_ALG_DETERMINISTIC_ECDSA #endif /** @@ -653,33 +615,6 @@ #undef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED #endif -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - * - * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - */ -#ifdef CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_PSK -#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED -#else -#undef MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED -#endif - /** * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED * @@ -703,94 +638,6 @@ #undef MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED #endif -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - * - * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - */ -#ifdef CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED -#else -#undef MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED -#endif - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - * - * Enable the RSA-only based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - */ -#ifdef CONFIG_MBEDTLS_KEY_EXCHANGE_RSA -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#else -#undef MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#endif - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - * - * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - */ -#ifdef CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA -#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED -#else -#undef MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED -#endif - /** * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED * @@ -846,60 +693,6 @@ #undef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED #endif -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - * - * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#ifdef CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA -#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED -#else -#undef MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED -#endif - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - * - * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#ifdef CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA -#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED -#else -#undef MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED -#endif - /** * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED * @@ -977,19 +770,6 @@ #undef MBEDTLS_ERROR_STRERROR_DUMMY #endif -/** - * \def MBEDTLS_GENPRIME - * - * Enable the prime-number generation code. - * - * Requires: MBEDTLS_BIGNUM_C - */ -#ifdef CONFIG_MBEDTLS_GENPRIME -#define MBEDTLS_GENPRIME -#else -#undef MBEDTLS_GENPRIME -#endif - /** * \def MBEDTLS_FS_IO * @@ -1004,16 +784,25 @@ #endif #ifndef CONFIG_IDF_TARGET_LINUX + /** - * \def MBEDTLS_NO_PLATFORM_ENTROPY + * \def MBEDTLS_PSA_ITS_FILE_C * - * Do not use built-in platform entropy functions. - * This is useful if your platform does not support - * standards like the /dev/urandom or Windows CryptoAPI. + * ESP-IDF: PSA Internal Trusted Storage (ITS) implementation. + * + * ESP-IDF does NOT use the file-based implementation (MBEDTLS_PSA_ITS_FILE_C) + * when the ESP-IDF NVS-based implementation is available. + * Instead, ESP-IDF provides its own NVS (Non-Volatile Storage) based implementation + * in port/psa_crypto_storage/esp_psa_its.c + * + * If ESP_PSA_ITS_AVAILABLE is defined, it means the ESP-IDF NVS-based implementation + * is available and we should undefine MBEDTLS_PSA_ITS_FILE_C to use it. + * Otherwise, keep MBEDTLS_PSA_ITS_FILE_C defined to use the file-based implementation. * - * Uncomment this macro to disable the built-in platform entropy functions. */ -#define MBEDTLS_NO_PLATFORM_ENTROPY +#ifdef ESP_PSA_ITS_AVAILABLE +#undef MBEDTLS_PSA_ITS_FILE_C +#endif #endif // !CONFIG_IDF_TARGET_LINUX /** @@ -1036,19 +825,6 @@ #undef MBEDTLS_ENTROPY_FORCE_SHA256 #endif -/** - * \def MBEDTLS_PK_RSA_ALT_SUPPORT - * - * Support external private RSA keys (eg from a HSM) in the PK layer. - * - * Comment this macro to disable support for external private RSA keys. - */ -#ifdef CONFIG_MBEDTLS_PK_RSA_ALT_SUPPORT -#define MBEDTLS_PK_RSA_ALT_SUPPORT -#else -#undef MBEDTLS_PK_RSA_ALT_SUPPORT -#endif - /** * \def MBEDTLS_PKCS1_V15 * @@ -1059,9 +835,11 @@ * This enables support for PKCS#1 v1.5 operations. */ #ifdef CONFIG_MBEDTLS_PKCS1_V15 -#define MBEDTLS_PKCS1_V15 +#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1 #else -#undef MBEDTLS_PKCS1_V15 +#undef PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +#undef PSA_WANT_ALG_RSA_PKCS1V15_SIGN #endif /** @@ -1074,9 +852,9 @@ * This enables support for RSAES-OAEP and RSASSA-PSS operations. */ #ifdef CONFIG_MBEDTLS_PKCS1_V21 -#define MBEDTLS_PKCS1_V21 +#define PSA_WANT_ALG_RSA_OAEP 1 #else -#undef MBEDTLS_PKCS1_V21 +#undef PSA_WANT_ALG_RSA_OAEP #endif /** @@ -1930,9 +1708,32 @@ * PEM_PARSE uses AES for decrypting encrypted keys. */ #ifdef CONFIG_MBEDTLS_AES_C -#define MBEDTLS_AES_C +#define PSA_WANT_KEY_TYPE_AES 1 #else +#undef PSA_WANT_KEY_TYPE_AES +#endif + +/* The following units have ESP32 hardware support, + uncommenting each _ALT macro will use the + hardware-accelerated implementation. */ +#ifdef CONFIG_MBEDTLS_HARDWARE_AES +#define MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING +#undef MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING +#define MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7 +#undef MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7 +#define MBEDTLS_PSA_ACCEL_ALG_CCM +#undef MBEDTLS_PSA_BUILTIN_ALG_CCM +#define MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG +#undef MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG +#define MBEDTLS_PSA_ACCEL_ALG_CMAC +#undef MBEDTLS_PSA_BUILTIN_ALG_CMAC +#define MBEDTLS_PSA_ACCEL_ALG_CFB +#undef MBEDTLS_PSA_BUILTIN_ALG_CFB #undef MBEDTLS_AES_C +#define MBEDTLS_PSA_ACCEL_ALG_CTR +#undef MBEDTLS_PSA_BUILTIN_ALG_CTR +#else +#undef MBEDTLS_AES_ALT #endif /** @@ -2081,6 +1882,7 @@ #define MBEDTLS_CAMELLIA_C #else #undef MBEDTLS_CAMELLIA_C +#undef PSA_WANT_KEY_TYPE_CAMELLIA #endif /** @@ -2134,9 +1936,9 @@ * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */ #ifdef CONFIG_MBEDTLS_ARIA_C -#define MBEDTLS_ARIA_C +#define PSA_WANT_KEY_TYPE_ARIA 1 #else -#undef MBEDTLS_ARIA_C +#undef PSA_WANT_KEY_TYPE_ARIA #endif /** @@ -2146,16 +1948,16 @@ * * Module: library/ccm.c * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or * MBEDTLS_ARIA_C * * This module enables the AES-CCM ciphersuites, if other requisites are * enabled as well. */ #ifdef CONFIG_MBEDTLS_CCM_C -#define MBEDTLS_CCM_C +#define PSA_WANT_ALG_CCM 1 #else -#undef MBEDTLS_CCM_C +#undef PSA_WANT_ALG_CCM #endif /** @@ -2198,32 +2000,6 @@ #undef MBEDTLS_CHACHAPOLY_C #endif -/** - * \def MBEDTLS_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: library/ccm.c - * library/cmac.c - * library/gcm.c - * library/nist_kw.c - * library/pkcs12.c - * library/pkcs5.c - * library/psa_crypto_aead.c - * library/psa_crypto_mac.c - * library/ssl_ciphersuites.c - * library/ssl_msg.c - * library/ssl_ticket.c (unless MBEDTLS_USE_PSA_CRYPTO is enabled) - * - * Uncomment to enable generic cipher wrappers. - */ -#ifdef CONFIG_MBEDTLS_CIPHER_C -#define MBEDTLS_CIPHER_C -#else -#undef MBEDTLS_CIPHER_C -#endif - /** * \def MBEDTLS_CTR_DRBG_C * @@ -2291,25 +2067,6 @@ #undef MBEDTLS_DES_C #endif -/** - * \def MBEDTLS_DHM_C - * - * Enable the Diffie-Hellman-Merkle module. - * - * Module: library/dhm.c - * Caller: library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module is used by the following key exchanges: - * DHE-RSA, DHE-PSK - */ -#ifdef CONFIG_MBEDTLS_DHM_C -#define MBEDTLS_DHM_C -#else -#undef MBEDTLS_DHM_C -#endif - /** * \def MBEDTLS_ECDH_C * @@ -2395,24 +2152,6 @@ #undef MBEDTLS_ECP_C #endif -/** - * \def MBEDTLS_ENTROPY_C - * - * Enable the platform-specific entropy code. - * - * Module: library/entropy.c - * Caller: - * - * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C - * - * This module provides a generic entropy pool - */ -#ifdef CONFIG_MBEDTLS_ENTROPY_C -#define MBEDTLS_ENTROPY_C -#else -#undef MBEDTLS_ENTROPY_C -#endif - /** * \def MBEDTLS_ERROR_C * @@ -2451,35 +2190,16 @@ * * Module: library/gcm.c * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or * MBEDTLS_ARIA_C * * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other * requisites are enabled as well. */ #ifdef CONFIG_MBEDTLS_GCM_C -#define MBEDTLS_GCM_C +#define PSA_WANT_ALG_GCM 1 #else -#undef MBEDTLS_GCM_C -#endif - -/** - * \def MBEDTLS_HKDF_C - * - * Enable the HKDF algorithm (RFC 5869). - * - * Module: library/hkdf.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * This module enables support for the Hashed Message Authentication Code - * (HMAC)-based key derivation function (HKDF). - */ -#ifdef CONFIG_MBEDTLS_HKDF_C -#define MBEDTLS_HKDF_C -#else -#undef MBEDTLS_HKDF_C +#undef PSA_WANT_ALG_GCM #endif /** @@ -2567,9 +2287,10 @@ * PEM_PARSE uses MD5 for decrypting encrypted keys. */ #ifdef CONFIG_MBEDTLS_MD5_C -#define MBEDTLS_MD5_C +#define PSA_WANT_ALG_MD5 1 #else #undef MBEDTLS_MD5_C +#undef PSA_WANT_ALG_MD5 #endif /** @@ -2593,33 +2314,6 @@ #undef MBEDTLS_NET_C #endif -/** - * \def MBEDTLS_OID_C - * - * Enable the OID database. - * - * Module: library/oid.c - * Caller: library/asn1write.c - * library/pkcs5.c - * library/pkparse.c - * library/pkwrite.c - * library/rsa.c - * library/x509.c - * library/x509_create.c - * library/mbedtls_x509_crl.c - * library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c - * library/x509write_crt.c - * library/mbedtls_x509write_csr.c - * - * This modules translates between OIDs and internal values. - */ -#ifdef CONFIG_MBEDTLS_OID_C -#define MBEDTLS_OID_C -#else -#undef MBEDTLS_OID_C -#endif - /** * \def MBEDTLS_PADLOCK_C * @@ -2744,7 +2438,7 @@ * * Module: library/pkcs5.c * - * Requires: MBEDTLS_CIPHER_C and MBEDTLS_MD_C + * Requires: MBEDTLS_MD_C * * This module adds support for the PKCS#5 functions. */ @@ -2778,25 +2472,6 @@ #undef MBEDTLS_PKCS7_C #endif -/** - * \def MBEDTLS_PKCS12_C - * - * Enable PKCS#12 PBE functions. - * Adds algorithms for parsing PKCS#8 encrypted private keys - * - * Module: library/pkcs12.c - * Caller: library/pkparse.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * - * This module enables PKCS#12 functions. - */ -#ifdef CONFIG_MBEDTLS_PKCS12_C -#define MBEDTLS_PKCS12_C -#else -#undef MBEDTLS_PKCS12_C -#endif - /** * \def MBEDTLS_PLATFORM_C * @@ -2844,6 +2519,7 @@ #define MBEDTLS_RIPEMD160_C #else #undef MBEDTLS_RIPEMD160_C +#undef PSA_WANT_ALG_RIPEMD160 #endif /** @@ -2865,9 +2541,11 @@ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C */ #ifdef CONFIG_MBEDTLS_RSA_C -#define MBEDTLS_RSA_C +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1 +#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 #else -#undef MBEDTLS_RSA_C +#undef PSA_WANT_KEY_TYPE_RSA_KEY_PAIR +#undef PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY #endif /** @@ -2888,9 +2566,9 @@ * */ #if CONFIG_MBEDTLS_SHA1_C -#define MBEDTLS_SHA1_C +#define PSA_WANT_ALG_SHA_1 1 #else -#undef MBEDTLS_SHA1_C +#undef PSA_WANT_ALG_SHA_1 #endif /** * \def MBEDTLS_SHA224_C @@ -2913,24 +2591,22 @@ #endif /** - * \def MBEDTLS_SHA256_C + * \def MBEDTLS_SHA512_C * - * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. * - * Module: library/mbedtls_sha256.c + * Module: library/sha512.c * Caller: library/entropy.c - * library/mbedtls_md.c + * library/md.c * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c= + * library/ssl_cookie.c * - * This module adds support for SHA-224 and SHA-256. - * This module is required for the SSL/TLS 1.2 PRF function. + * This module adds support for SHA-384 and SHA-512. */ -#ifdef CONFIG_MBEDTLS_SHA256_C -#define MBEDTLS_SHA256_C +#ifdef CONFIG_MBEDTLS_SHA512_C +#define PSA_WANT_ALG_SHA_512 1 #else -#undef MBEDTLS_SHA256_C +#undef PSA_WANT_ALG_SHA_512 #endif /** @@ -2948,28 +2624,85 @@ * Comment to disable SHA-384 */ #ifdef CONFIG_MBEDTLS_SHA384_C -#define MBEDTLS_SHA384_C +#define PSA_WANT_ALG_SHA_384 1 #else -#undef MBEDTLS_SHA384_C +#undef PSA_WANT_ALG_SHA_384 #endif /** - * \def MBEDTLS_SHA512_C + * \def MBEDTLS_SHA256_C * - * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. * - * Module: library/sha512.c + * Module: library/mbedtls_sha256.c * Caller: library/entropy.c - * library/md.c + * library/mbedtls_md.c * library/ssl_tls.c - * library/ssl_cookie.c + * library/ssl*_client.c + * library/ssl*_server.c= * - * This module adds support for SHA-384 and SHA-512. + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. */ -#ifdef CONFIG_MBEDTLS_SHA512_C -#define MBEDTLS_SHA512_C +#ifdef CONFIG_MBEDTLS_SHA256_C +#define MBEDTLS_SHA256_C +#define PSA_WANT_ALG_SHA_256 1 +#define PSA_WANT_ALG_SHA_224 1 #else -#undef MBEDTLS_SHA512_C +#undef PSA_WANT_ALG_SHA_256 +#undef PSA_WANT_ALG_SHA_224 +#endif + +/* MBEDTLS_SHAxx_ALT to enable hardware SHA support + with software fallback. +*/ +#ifdef CONFIG_MBEDTLS_HARDWARE_SHA + #define MBEDTLS_PSA_ACCEL_ALG_SHA_1 + #undef MBEDTLS_PSA_BUILTIN_ALG_SHA_1 + #define MBEDTLS_PSA_ACCEL_ALG_SHA_224 + #undef MBEDTLS_PSA_BUILTIN_ALG_SHA_224 + #define MBEDTLS_PSA_ACCEL_ALG_SHA_256 + #undef MBEDTLS_PSA_BUILTIN_ALG_SHA_256 + #undef MBEDTLS_SHA1_C + #undef MBEDTLS_SHA224_C + #if SOC_SHA_SUPPORT_SHA512 + #define MBEDTLS_PSA_ACCEL_ALG_SHA_512 + #undef MBEDTLS_PSA_BUILTIN_ALG_SHA_512 + #define MBEDTLS_PSA_ACCEL_ALG_SHA_384 + #undef MBEDTLS_PSA_BUILTIN_ALG_SHA_384 + #undef MBEDTLS_SHA512_C + #undef MBEDTLS_SHA384_C + #else + #undef MBEDTLS_SHA512_ALT + #endif +#else + #undef MBEDTLS_SHA1_ALT + #undef MBEDTLS_SHA256_ALT + #undef MBEDTLS_SHA512_ALT +#endif + +/* MBEDTLS_MD_CAN_SHA* macros indicate whether a hash algorithm is available + * either via legacy implementation (MBEDTLS_SHA*_C) or via PSA (PSA_WANT_ALG_SHA_*). + * These are used for TLS 1.3 signature algorithm configuration. + */ +#if defined(MBEDTLS_SHA1_C) || defined(PSA_WANT_ALG_SHA_1) +#define MBEDTLS_MD_CAN_SHA1 +#endif + +#if defined(MBEDTLS_SHA224_C) || defined(PSA_WANT_ALG_SHA_224) +#define MBEDTLS_MD_CAN_SHA224 +#endif + +#if defined(MBEDTLS_SHA256_C) || defined(PSA_WANT_ALG_SHA_256) +#define MBEDTLS_MD_CAN_SHA256 +#endif + +#if defined(MBEDTLS_SHA384_C) || defined(PSA_WANT_ALG_SHA_384) +#define MBEDTLS_MD_CAN_SHA384 +#endif + +#if defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512) +#define MBEDTLS_MD_CAN_SHA512 #endif /** @@ -2982,9 +2715,15 @@ * This module adds support for SHA3. */ #ifdef CONFIG_MBEDTLS_SHA3_C -#define MBEDTLS_SHA3_C +#define PSA_WANT_ALG_SHA3_224 1 +#define PSA_WANT_ALG_SHA3_256 1 +#define PSA_WANT_ALG_SHA3_384 1 +#define PSA_WANT_ALG_SHA3_512 1 #else -#undef MBEDTLS_SHA3_C +#undef PSA_WANT_ALG_SHA3_224 +#undef PSA_WANT_ALG_SHA3_256 +#undef PSA_WANT_ALG_SHA3_384 +#undef PSA_WANT_ALG_SHA3_512 #endif /** @@ -3025,8 +2764,7 @@ * Module: library/ssl_ticket.c * Caller: * - * Requires: (MBEDTLS_CIPHER_C) && - * (MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C) + * Requires: (MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C) */ #ifdef CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS #define MBEDTLS_SSL_TICKET_C @@ -3079,7 +2817,7 @@ * Caller: library/ssl*_client.c * library/ssl*_server.c * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Requires: MBEDTLS_MD_C * and at least one of the MBEDTLS_SSL_PROTO_XXX defines * * This module is required for SSL/TLS. diff --git a/components/mbedtls/port/include/mbedtls/esp_debug.h b/components/mbedtls/port/include/mbedtls/esp_debug.h index ecd4688f9c2..a74361c002e 100644 --- a/components/mbedtls/port/include/mbedtls/esp_debug.h +++ b/components/mbedtls/port/include/mbedtls/esp_debug.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ESP_DEBUG_H_ #define _ESP_DEBUG_H_ @@ -40,7 +32,7 @@ extern "C" { * enough in menuconfig, or some messages may be filtered at compile time. * * @param conf mbedtls_ssl_config structure - * @param mbedTLS debug threshold, 0-4. Messages are filtered at runtime. + * @param threshold mbedTLS debug threshold, 0-4. Messages are filtered at runtime. */ void mbedtls_esp_enable_debug_log(mbedtls_ssl_config *conf, int threshold); diff --git a/components/mbedtls/port/include/mbedtls/gcm.h b/components/mbedtls/port/include/mbedtls/gcm.h index d50527d4df5..a2c9009d0d0 100644 --- a/components/mbedtls/port/include/mbedtls/gcm.h +++ b/components/mbedtls/port/include/mbedtls/gcm.h @@ -1,11 +1,10 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -#include_next "mbedtls/gcm.h" #include "sdkconfig.h" #ifdef __cplusplus @@ -14,66 +13,6 @@ extern "C" { #if defined(MBEDTLS_GCM_ALT) && defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) -/** - * When the MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK is defined, for non-AES GCM - * operations we need to fallback to the software function definitions of the - * mbedtls GCM layer. - * Thus in this case we need declarations for the software funtions. - * Please refer mbedtls/include/mbedtls/gcm.h for function documentations - */ - -void mbedtls_gcm_init_soft(mbedtls_gcm_context_soft *ctx); - - -int mbedtls_gcm_setkey_soft(mbedtls_gcm_context_soft *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits); - -int mbedtls_gcm_starts_soft(mbedtls_gcm_context_soft *ctx, - int mode, - const unsigned char *iv, size_t iv_len); - -int mbedtls_gcm_update_ad_soft(mbedtls_gcm_context_soft *ctx, - const unsigned char *add, size_t add_len); - -int mbedtls_gcm_update_soft(mbedtls_gcm_context_soft *ctx, - const unsigned char *input, size_t input_length, - unsigned char *output, size_t output_size, - size_t *output_length); - -int mbedtls_gcm_finish_soft(mbedtls_gcm_context_soft *ctx, - unsigned char *output, size_t output_size, - size_t *output_length, - unsigned char *tag, size_t tag_len); - - -int mbedtls_gcm_crypt_and_tag_soft(mbedtls_gcm_context_soft *ctx, - int mode, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *input, - unsigned char *output, - size_t tag_len, - unsigned char *tag); - - -int mbedtls_gcm_auth_decrypt_soft(mbedtls_gcm_context_soft *ctx, - size_t length, - const unsigned char *iv, - size_t iv_len, - const unsigned char *add, - size_t add_len, - const unsigned char *tag, - size_t tag_len, - const unsigned char *input, - unsigned char *output); - -void mbedtls_gcm_free_soft(mbedtls_gcm_context_soft *ctx); - #endif /* MBEDTLS_GCM_ALT && MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK*/ #ifdef __cplusplus diff --git a/components/mbedtls/port/psa_crypto_storage/esp_psa_its.c b/components/mbedtls/port/psa_crypto_storage/esp_psa_its.c new file mode 100644 index 00000000000..89a5f693f88 --- /dev/null +++ b/components/mbedtls/port/psa_crypto_storage/esp_psa_its.c @@ -0,0 +1,453 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + * PSA ITS (Internal Trusted Storage) implementation using ESP-IDF NVS. + * + * This file provides the PSA Internal Trusted Storage API using ESP-IDF's + * NVS (Non-Volatile Storage) flash storage instead of a filesystem. + * This is suitable for embedded systems without filesystem support. + */ + +#include "mbedtls/platform.h" +#include "mbedtls/platform_util.h" +#include "psa_crypto_its.h" + +#include +#include +#include + +/* ESP-IDF specific includes */ +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_log.h" + +static const char *TAG = "esp_psa_its"; + +/* NVS namespace for PSA ITS */ +#define PSA_ITS_NVS_NAMESPACE "psa_its" + +/* The maximum value of psa_storage_info_t.size */ +#define PSA_ITS_MAX_SIZE 0xffffffff + +/* Magic number for entry validation: 'PSAI' */ +#define PSA_ITS_MAGIC 0x50534149 + +/* NVS key length limit is 15 characters + null terminator */ +#define PSA_ITS_NVS_KEY_LEN 14 /* 13 chars + null */ + +/** + * Storage entry format stored in NVS blob: + * - magic: 4 bytes (0x50534149 'PSAI') + * - flags: 4 bytes (PSA storage flags) + * - size: 4 bytes (data size) + * - data: variable length + */ +typedef struct { + uint32_t magic; + uint32_t flags; + uint32_t size; + uint8_t data[]; +} __attribute__((packed)) psa_its_entry_t; + +/** + * Convert 64-bit UID to 13-character base32 NVS key. + * Uses RFC 4648 base32 alphabet: A-Z, 2-7 (32 characters). + * 64 bits / 5 bits per char = 12.8, needs 13 chars + null terminator. + */ +static void uid_to_nvs_key(psa_storage_uid_t uid, char *key) +{ + static const char base32_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + + /* Encode 64-bit UID as 13 base32 characters */ + for (int i = 0; i < 13; i++) { + key[12 - i] = base32_alphabet[uid & 0x1F]; + uid >>= 5; + } + key[13] = '\0'; +} + +/** + * Map ESP error codes to PSA status codes. + */ +static psa_status_t esp_err_to_psa_status(esp_err_t err) +{ + switch (err) { + case ESP_OK: + return PSA_SUCCESS; + case ESP_ERR_NVS_NOT_FOUND: + return PSA_ERROR_DOES_NOT_EXIST; + case ESP_ERR_NVS_NOT_ENOUGH_SPACE: + case ESP_ERR_NVS_NO_FREE_PAGES: + return PSA_ERROR_INSUFFICIENT_STORAGE; + case ESP_ERR_NVS_INVALID_LENGTH: + case ESP_ERR_NVS_INVALID_NAME: + return PSA_ERROR_INVALID_ARGUMENT; + default: + return PSA_ERROR_STORAGE_FAILURE; + } +} + +/** + * Get storage information for a UID. + */ +psa_status_t psa_its_get_info(psa_storage_uid_t uid, + struct psa_storage_info_t *p_info) +{ + nvs_handle_t handle; + esp_err_t err; + char nvs_key[PSA_ITS_NVS_KEY_LEN]; + size_t required_size = 0; + psa_its_entry_t *entry = NULL; + psa_status_t status = PSA_ERROR_STORAGE_FAILURE; + + if (p_info == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + /* Convert UID to NVS key */ + uid_to_nvs_key(uid, nvs_key); + + /* Open NVS handle */ + err = nvs_open(PSA_ITS_NVS_NAMESPACE, NVS_READONLY, &handle); + if (err == ESP_ERR_NVS_NOT_FOUND) { + /* Namespace doesn't exist yet, which means key doesn't exist */ + return PSA_ERROR_DOES_NOT_EXIST; + } + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to open NVS namespace: %s", esp_err_to_name(err)); + return esp_err_to_psa_status(err); + } + + /* Get the blob size first */ + err = nvs_get_blob(handle, nvs_key, NULL, &required_size); + if (err != ESP_OK) { + status = esp_err_to_psa_status(err); + goto exit; + } + + /* Check minimum size for header */ + if (required_size < sizeof(psa_its_entry_t)) { + ESP_LOGE(TAG, "Corrupted entry: size too small"); + status = PSA_ERROR_DATA_CORRUPT; + goto exit; + } + + /* Allocate and read entry header */ + entry = mbedtls_calloc(1, required_size); + if (entry == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto exit; + } + + err = nvs_get_blob(handle, nvs_key, entry, &required_size); + if (err != ESP_OK) { + status = esp_err_to_psa_status(err); + goto exit; + } + + /* Validate magic number */ + if (entry->magic != PSA_ITS_MAGIC) { + ESP_LOGE(TAG, "Invalid magic number: 0x%08lx", (unsigned long)entry->magic); + status = PSA_ERROR_DATA_CORRUPT; + goto exit; + } + + /* Return info */ + p_info->size = entry->size; + p_info->flags = entry->flags; + status = PSA_SUCCESS; + +exit: + if (entry != NULL) { + mbedtls_platform_zeroize(entry, required_size); + mbedtls_free(entry); + } + nvs_close(handle); + return status; +} + +/** + * Retrieve data from storage. + */ +psa_status_t psa_its_get(psa_storage_uid_t uid, + uint32_t data_offset, + uint32_t data_length, + void *p_data, + size_t *p_data_length) +{ + nvs_handle_t handle; + esp_err_t err; + char nvs_key[PSA_ITS_NVS_KEY_LEN]; + size_t required_size = 0; + psa_its_entry_t *entry = NULL; + psa_status_t status = PSA_ERROR_STORAGE_FAILURE; + + if (p_data == NULL && data_length != 0) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + /* Convert UID to NVS key */ + uid_to_nvs_key(uid, nvs_key); + + /* Open NVS handle */ + err = nvs_open(PSA_ITS_NVS_NAMESPACE, NVS_READONLY, &handle); + if (err == ESP_ERR_NVS_NOT_FOUND) { + return PSA_ERROR_DOES_NOT_EXIST; + } + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to open NVS namespace: %s", esp_err_to_name(err)); + return esp_err_to_psa_status(err); + } + + /* Get the blob size */ + err = nvs_get_blob(handle, nvs_key, NULL, &required_size); + if (err != ESP_OK) { + status = esp_err_to_psa_status(err); + goto exit; + } + + /* Check minimum size */ + if (required_size < sizeof(psa_its_entry_t)) { + ESP_LOGE(TAG, "Corrupted entry: size too small"); + status = PSA_ERROR_DATA_CORRUPT; + goto exit; + } + + /* Allocate and read full entry */ + entry = mbedtls_calloc(1, required_size); + if (entry == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto exit; + } + + err = nvs_get_blob(handle, nvs_key, entry, &required_size); + if (err != ESP_OK) { + status = esp_err_to_psa_status(err); + goto exit; + } + + /* Validate magic number */ + if (entry->magic != PSA_ITS_MAGIC) { + ESP_LOGE(TAG, "Invalid magic number: 0x%08lx", (unsigned long)entry->magic); + status = PSA_ERROR_DATA_CORRUPT; + goto exit; + } + + /* Validate offset and length */ + if (data_offset + data_length < data_offset) { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } +#if SIZE_MAX < 0xffffffff + if (data_offset + data_length > SIZE_MAX) { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } +#endif + if (data_offset + data_length > entry->size) { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } + + /* Copy requested data portion */ + if (data_length > 0) { + memcpy(p_data, entry->data + data_offset, data_length); + } + + if (p_data_length != NULL) { + *p_data_length = data_length; + } + + status = PSA_SUCCESS; + +exit: + if (entry != NULL) { + mbedtls_platform_zeroize(entry, required_size); + mbedtls_free(entry); + } + nvs_close(handle); + return status; +} + +/** + * Store data in NVS. + */ +psa_status_t psa_its_set(psa_storage_uid_t uid, + uint32_t data_length, + const void *p_data, + psa_storage_create_flags_t create_flags) +{ + nvs_handle_t handle; + esp_err_t err; + char nvs_key[PSA_ITS_NVS_KEY_LEN]; + psa_its_entry_t *entry = NULL; + size_t entry_size; + size_t existing_size = 0; + psa_its_entry_t *existing_entry = NULL; + psa_status_t status = PSA_ERROR_STORAGE_FAILURE; + + /* UID 0 is invalid per PSA spec */ + if (uid == 0) { + return PSA_ERROR_INVALID_HANDLE; + } + + if (p_data == NULL && data_length != 0) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + /* Convert UID to NVS key */ + uid_to_nvs_key(uid, nvs_key); + + /* Open NVS handle with read-write access */ + err = nvs_open(PSA_ITS_NVS_NAMESPACE, NVS_READWRITE, &handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to open NVS namespace: %s", esp_err_to_name(err)); + return esp_err_to_psa_status(err); + } + + /* Check if entry already exists and has WRITE_ONCE flag */ + err = nvs_get_blob(handle, nvs_key, NULL, &existing_size); + if (err == ESP_OK && existing_size >= sizeof(psa_its_entry_t)) { + /* Entry exists, check WRITE_ONCE flag */ + existing_entry = mbedtls_calloc(1, existing_size); + if (existing_entry != NULL) { + err = nvs_get_blob(handle, nvs_key, existing_entry, &existing_size); + if (err == ESP_OK && + existing_entry->magic == PSA_ITS_MAGIC && + (existing_entry->flags & PSA_STORAGE_FLAG_WRITE_ONCE)) { + ESP_LOGW(TAG, "Cannot modify WRITE_ONCE entry"); + status = PSA_ERROR_NOT_PERMITTED; + mbedtls_platform_zeroize(existing_entry, existing_size); + mbedtls_free(existing_entry); + goto exit; + } + mbedtls_platform_zeroize(existing_entry, existing_size); + mbedtls_free(existing_entry); + } + } + + /* Allocate entry with header + data */ + entry_size = sizeof(psa_its_entry_t) + data_length; + entry = mbedtls_calloc(1, entry_size); + if (entry == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto exit; + } + + /* Fill entry */ + entry->magic = PSA_ITS_MAGIC; + entry->flags = create_flags; + entry->size = data_length; + if (data_length > 0) { + memcpy(entry->data, p_data, data_length); + } + + /* Write to NVS */ + err = nvs_set_blob(handle, nvs_key, entry, entry_size); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to write blob: %s", esp_err_to_name(err)); + status = esp_err_to_psa_status(err); + goto exit; + } + + /* Commit to ensure atomicity */ + err = nvs_commit(handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to commit: %s", esp_err_to_name(err)); + status = esp_err_to_psa_status(err); + goto exit; + } + + status = PSA_SUCCESS; + +exit: + if (entry != NULL) { + mbedtls_platform_zeroize(entry, entry_size); + mbedtls_free(entry); + } + nvs_close(handle); + return status; +} + +/** + * Remove data from storage. + */ +psa_status_t psa_its_remove(psa_storage_uid_t uid) +{ + nvs_handle_t handle; + esp_err_t err; + char nvs_key[PSA_ITS_NVS_KEY_LEN]; + size_t existing_size = 0; + psa_its_entry_t *existing_entry = NULL; + psa_status_t status = PSA_ERROR_STORAGE_FAILURE; + + /* Convert UID to NVS key */ + uid_to_nvs_key(uid, nvs_key); + + /* Open NVS handle */ + err = nvs_open(PSA_ITS_NVS_NAMESPACE, NVS_READWRITE, &handle); + if (err == ESP_ERR_NVS_NOT_FOUND) { + return PSA_ERROR_DOES_NOT_EXIST; + } + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to open NVS namespace: %s", esp_err_to_name(err)); + return esp_err_to_psa_status(err); + } + + /* Check if entry exists and has WRITE_ONCE flag */ + err = nvs_get_blob(handle, nvs_key, NULL, &existing_size); + if (err == ESP_ERR_NVS_NOT_FOUND) { + status = PSA_ERROR_DOES_NOT_EXIST; + goto exit; + } + if (err != ESP_OK) { + status = esp_err_to_psa_status(err); + goto exit; + } + + if (existing_size >= sizeof(psa_its_entry_t)) { + /* Read entry to check WRITE_ONCE flag */ + existing_entry = mbedtls_calloc(1, existing_size); + if (existing_entry == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto exit; + } + + err = nvs_get_blob(handle, nvs_key, existing_entry, &existing_size); + if (err == ESP_OK && + existing_entry->magic == PSA_ITS_MAGIC && + (existing_entry->flags & PSA_STORAGE_FLAG_WRITE_ONCE)) { + ESP_LOGW(TAG, "Cannot remove WRITE_ONCE entry"); + status = PSA_ERROR_NOT_PERMITTED; + goto exit; + } + } + + /* Erase the key */ + err = nvs_erase_key(handle, nvs_key); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to erase key: %s", esp_err_to_name(err)); + status = esp_err_to_psa_status(err); + goto exit; + } + + /* Commit to ensure atomicity */ + err = nvs_commit(handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to commit: %s", esp_err_to_name(err)); + status = esp_err_to_psa_status(err); + goto exit; + } + + status = PSA_SUCCESS; + +exit: + if (existing_entry != NULL) { + mbedtls_platform_zeroize(existing_entry, existing_size); + mbedtls_free(existing_entry); + } + nvs_close(handle); + return status; +} diff --git a/components/mbedtls/port/psa_crypto_storage/include/psa/error.h b/components/mbedtls/port/psa_crypto_storage/include/psa/error.h new file mode 100644 index 00000000000..1dc6456feca --- /dev/null +++ b/components/mbedtls/port/psa_crypto_storage/include/psa/error.h @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "psa/crypto_values.h" diff --git a/components/mbedtls/port/psa_crypto_storage/include/psa/internal_trusted_storage.h b/components/mbedtls/port/psa_crypto_storage/include/psa/internal_trusted_storage.h new file mode 100644 index 00000000000..dd46b4d77da --- /dev/null +++ b/components/mbedtls/port/psa_crypto_storage/include/psa/internal_trusted_storage.h @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "psa_crypto_its.h" diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c new file mode 100644 index 00000000000..ad18760de11 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes.c @@ -0,0 +1,689 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_aes.h" +#include "../include/psa_crypto_driver_esp_aes_contexts.h" +#include "esp_aes.h" +#include "psa_crypto_core.h" +#include "constant_time_internal.h" +#include "esp_log.h" + +static psa_status_t esp_crypto_aes_ecb_update( + esp_aes_operation_t *esp_aes_driver_ctx, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t *output_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + *output_length = 0; + + esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx; + + if (esp_aes_driver_ctx->unprocessed_len > 0) { + /* Fill up to block size, and run the block if there's a full one. */ + size_t bytes_to_copy = esp_aes_driver_ctx->block_length - esp_aes_driver_ctx->unprocessed_len; + + if (input_length < bytes_to_copy) { + bytes_to_copy = input_length; + } + + memcpy(&(esp_aes_driver_ctx->unprocessed_data[esp_aes_driver_ctx->unprocessed_len]), input, bytes_to_copy); + input_length -= bytes_to_copy; + input += bytes_to_copy; + esp_aes_driver_ctx->unprocessed_len += bytes_to_copy; + + if (esp_aes_driver_ctx->unprocessed_len == esp_aes_driver_ctx->block_length) { + status = mbedtls_to_psa_error(esp_aes_crypt_ecb(ctx, esp_aes_driver_ctx->mode, esp_aes_driver_ctx->unprocessed_data, output)); + if (status != PSA_SUCCESS) { + goto exit; + } + + output += esp_aes_driver_ctx->block_length; + *output_length += esp_aes_driver_ctx->block_length; + esp_aes_driver_ctx->unprocessed_len = 0; + } + } + + while (input_length >= esp_aes_driver_ctx->block_length) { + /* Run all full blocks we have, one by one */ + status = mbedtls_to_psa_error(esp_aes_crypt_ecb(ctx, esp_aes_driver_ctx->mode, input, output)); + if (status != PSA_SUCCESS) { + goto exit; + } + + input_length -= esp_aes_driver_ctx->block_length; + input += esp_aes_driver_ctx->block_length; + + output += esp_aes_driver_ctx->block_length; + *output_length += esp_aes_driver_ctx->block_length; + } + + if (input_length > 0) { + /* Save unprocessed bytes for later processing */ + memcpy(&(esp_aes_driver_ctx->unprocessed_data[esp_aes_driver_ctx->unprocessed_len]), input, input_length); + esp_aes_driver_ctx->unprocessed_len += input_length; + } + + status = PSA_SUCCESS; +exit: + return status; +} + +static psa_status_t esp_crypto_aes_cbc_update( + esp_aes_operation_t *esp_aes_driver_ctx, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, + size_t *output_length) +{ + int ret = -1; + esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx; + size_t copy_len = 0; + *output_length = 0; + + /* + * If there is not enough data for a full block, cache it. + */ + if ((esp_aes_driver_ctx->mode == PSA_CRYPTO_DRIVER_DECRYPT && + esp_aes_driver_ctx->aes_alg != PSA_ALG_CBC_NO_PADDING && + input_length <= esp_aes_driver_ctx->block_length - esp_aes_driver_ctx->unprocessed_len) || + (esp_aes_driver_ctx->mode == PSA_CRYPTO_DRIVER_DECRYPT && + esp_aes_driver_ctx->aes_alg == PSA_ALG_CBC_NO_PADDING && + input_length < esp_aes_driver_ctx->block_length - esp_aes_driver_ctx->unprocessed_len) || + (esp_aes_driver_ctx->mode == PSA_CRYPTO_DRIVER_ENCRYPT && + input_length < esp_aes_driver_ctx->block_length - esp_aes_driver_ctx->unprocessed_len)) { + + memcpy(&(esp_aes_driver_ctx->unprocessed_data[esp_aes_driver_ctx->unprocessed_len]), input, input_length); + esp_aes_driver_ctx->unprocessed_len += input_length; + return PSA_SUCCESS; + } + + /* + * Process cached data first + */ + if (esp_aes_driver_ctx->unprocessed_len != 0) { + copy_len = esp_aes_driver_ctx->block_length - esp_aes_driver_ctx->unprocessed_len; + + memcpy(&(esp_aes_driver_ctx->unprocessed_data[esp_aes_driver_ctx->unprocessed_len]), input, copy_len); + + ret = esp_aes_crypt_cbc(ctx, + esp_aes_driver_ctx->mode, + esp_aes_driver_ctx->block_length, + esp_aes_driver_ctx->iv, + esp_aes_driver_ctx->unprocessed_data, + output); + if (ret != 0) { + goto exit; + } + + *output_length += esp_aes_driver_ctx->block_length; + output += esp_aes_driver_ctx->block_length; + esp_aes_driver_ctx->unprocessed_len = 0; + + input += copy_len; + input_length -= copy_len; + } + /* + * Cache final, incomplete block + */ + if (input_length != 0) { + /* Encryption: only cache partial blocks + * Decryption w/ padding: always keep at least one whole block + * Decryption w/o padding: only cache partial blocks + */ + copy_len = input_length % esp_aes_driver_ctx->block_length; + if (copy_len == 0 && + esp_aes_driver_ctx->mode == PSA_CRYPTO_DRIVER_DECRYPT && + esp_aes_driver_ctx->aes_alg != PSA_ALG_CBC_NO_PADDING) { + copy_len = esp_aes_driver_ctx->block_length; + } + + memcpy(esp_aes_driver_ctx->unprocessed_data, &(input[input_length - copy_len]), copy_len); + + esp_aes_driver_ctx->unprocessed_len += copy_len; + input_length -= copy_len; + } + /* + * Process remaining full blocks + */ + if (input_length) { + ret = esp_aes_crypt_cbc(ctx, esp_aes_driver_ctx->mode, + input_length, esp_aes_driver_ctx->iv, + input, + output); + if (ret != 0) { + goto exit; + } + + *output_length += input_length; + } + +exit: + return mbedtls_to_psa_error(ret); +} + +psa_status_t esp_crypto_aes_update( + esp_aes_operation_t *esp_aes_driver_ctx, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, + size_t *output_length) +{ + int ret = -1; + size_t expected_output_size; + *output_length = 0; + + if (!PSA_ALG_IS_STREAM_CIPHER(esp_aes_driver_ctx->aes_alg)) { + /* Take the unprocessed partial block left over from previous + * update calls, if any, plus the input to this call. Remove + * the last partial block, if any. You get the data that will be + * output in this call. */ + expected_output_size = (esp_aes_driver_ctx->unprocessed_len + input_length) / esp_aes_driver_ctx->block_length * esp_aes_driver_ctx->block_length; + } else { + expected_output_size = input_length; + } + + if (output_size < expected_output_size) { + ESP_LOGE("TAG", "Output buffer too small: have %zu, need %zu", output_size, expected_output_size); + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + if (input_length == 0) { + /* There is no input, nothing to be done */ + *output_length = 0; + return PSA_SUCCESS; + } + else if (esp_aes_driver_ctx->aes_alg == PSA_ALG_ECB_NO_PADDING) { + /* esp_aes_crypt_ecb will only process a single block at a time in + * ECB mode. Abstract this away to match the PSA API behaviour. */ + ret = esp_crypto_aes_ecb_update(esp_aes_driver_ctx, + input, + input_length, + output, + output_length); + } else { + if (input == output && + (esp_aes_driver_ctx->unprocessed_len != 0 || input_length % esp_aes_driver_ctx->block_length)) { + ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + goto exit; + } + + switch (esp_aes_driver_ctx->aes_alg) { +#if CONFIG_MBEDTLS_CIPHER_MODE_CTR + case PSA_ALG_CTR: + ret = esp_aes_crypt_ctr(esp_aes_driver_ctx->esp_aes_ctx, + input_length, + &esp_aes_driver_ctx->unprocessed_len, + esp_aes_driver_ctx->iv, + esp_aes_driver_ctx->unprocessed_data, + input, + output); + *output_length = input_length; + break; +#endif /* CONFIG_MBEDTLS_CIPHER_MODE_CTR */ +#if CONFIG_MBEDTLS_CIPHER_MODE_CFB + case PSA_ALG_CFB: + ret = esp_aes_crypt_cfb128(esp_aes_driver_ctx->esp_aes_ctx, + esp_aes_driver_ctx->mode, + input_length, + &esp_aes_driver_ctx->unprocessed_len, + esp_aes_driver_ctx->iv, + input, + output); + *output_length = input_length; + break; +#endif /* CONFIG_MBEDTLS_CIPHER_MODE_CFB */ +#if CONFIG_MBEDTLS_CIPHER_MODE_OFB + case PSA_ALG_OFB: + ret = esp_aes_crypt_ofb(esp_aes_driver_ctx->esp_aes_ctx, + input_length, + &esp_aes_driver_ctx->unprocessed_len, + esp_aes_driver_ctx->iv, + input, + output); + *output_length = input_length; + break; +#endif /* CONFIG_MBEDTLS_CIPHER_MODE_OFB */ + case PSA_ALG_CBC_NO_PADDING: + case PSA_ALG_CBC_PKCS7: + ret = esp_crypto_aes_cbc_update(esp_aes_driver_ctx, + input, + input_length, + output, + output_size, + output_length); + break; + default: + ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + goto exit; + } + + if (*output_length > output_size) { + return PSA_ERROR_CORRUPTION_DETECTED; + } + } + +exit: + return mbedtls_to_psa_error(ret); +} + +/* + * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len + */ +static void add_pkcs_padding(unsigned char *output, size_t output_len, + size_t data_len) +{ + size_t padding_len = output_len - data_len; + unsigned char i; + + for (i = 0; i < padding_len; i++) { + output[data_len + i] = (unsigned char) padding_len; + } +} + +static int get_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len) +{ + size_t i, pad_idx; + unsigned char padding_len; + + if (NULL == input || NULL == data_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + padding_len = input[input_len - 1]; + if (padding_len == 0 || padding_len > input_len) { + return MBEDTLS_ERR_CIPHER_INVALID_PADDING; + } + *data_len = input_len - padding_len; + + mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len); + bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0)); + + /* The number of bytes checked must be independent of padding_len, + * so pick input_len, which is usually 8 or 16 (one block) */ + pad_idx = input_len - padding_len; + for (i = 0; i < input_len; i++) { + mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx); + mbedtls_ct_condition_t different = mbedtls_ct_uint_ne(input[i], padding_len); + bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different)); + } + + return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING); +} + +psa_status_t esp_crypto_aes_finish( + esp_aes_operation_t *esp_aes_driver_ctx, + uint8_t *output, size_t output_size, + size_t *output_length) +{ + int ret = -1; + esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + uint8_t temp_output_buffer[ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH]; + + if (esp_aes_driver_ctx->unprocessed_len != 0) { + if (esp_aes_driver_ctx->aes_alg == PSA_ALG_ECB_NO_PADDING || + esp_aes_driver_ctx->aes_alg == PSA_ALG_CBC_NO_PADDING) { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } + } + + *output_length = 0; + switch (esp_aes_driver_ctx->aes_alg) { + case PSA_ALG_ECB_NO_PADDING: + case PSA_ALG_CTR: + case PSA_ALG_XTS: + case PSA_ALG_CFB: + case PSA_ALG_OFB: + status = PSA_SUCCESS; + break; + case PSA_ALG_CBC_PKCS7: + if (esp_aes_driver_ctx->mode == PSA_CRYPTO_DRIVER_ENCRYPT) { + /* PKCS7 padding: always add padding, even if data is block-aligned. + * If unprocessed_len == 0, we add a full padding block. + * Otherwise, we pad the partial block. */ + add_pkcs_padding(esp_aes_driver_ctx->unprocessed_data, esp_aes_driver_ctx->block_length, esp_aes_driver_ctx->unprocessed_len); + } else if (esp_aes_driver_ctx->unprocessed_len != esp_aes_driver_ctx->block_length) { + /* + * For decrypt operations, expect a full block, + * or an empty block if no padding + */ + if (esp_aes_driver_ctx->unprocessed_len == 0) { + status = PSA_SUCCESS; + break; + } + return mbedtls_to_psa_error(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED); + } + ret = esp_aes_crypt_cbc(ctx, esp_aes_driver_ctx->mode, + esp_aes_driver_ctx->block_length, + esp_aes_driver_ctx->iv, + esp_aes_driver_ctx->unprocessed_data, + temp_output_buffer); + if (ret != 0) { + return mbedtls_to_psa_error(ret); + } + + if (esp_aes_driver_ctx->mode == PSA_CRYPTO_DRIVER_DECRYPT) { + ret = get_pkcs_padding(temp_output_buffer, esp_aes_driver_ctx->block_length, output_length); + if (ret != 0) { + return mbedtls_to_psa_error(ret); + } + } else { + *output_length = esp_aes_driver_ctx->block_length; + } + status = PSA_SUCCESS; + + break; + case PSA_ALG_CBC_NO_PADDING: + if (esp_aes_driver_ctx->mode == PSA_CRYPTO_DRIVER_ENCRYPT) { + if (esp_aes_driver_ctx->unprocessed_len == 0) { + status = PSA_SUCCESS; + break; + } + } else if (esp_aes_driver_ctx->unprocessed_len != esp_aes_driver_ctx->block_length) { + if (esp_aes_driver_ctx->unprocessed_len == 0) { + return PSA_SUCCESS; + } + return mbedtls_to_psa_error(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED); + } + + ret = esp_aes_crypt_cbc(ctx, esp_aes_driver_ctx->mode, + esp_aes_driver_ctx->block_length, + esp_aes_driver_ctx->iv, + esp_aes_driver_ctx->unprocessed_data, + temp_output_buffer); + if (ret != 0) { + return mbedtls_to_psa_error(ret); + } + + *output_length = esp_aes_driver_ctx->block_length; + status = PSA_SUCCESS; + break; + default: + status = mbedtls_to_psa_error(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE); + goto exit; + } + + if (*output_length == 0) { + ; /* Nothing to copy. Note that output may be NULL in this case. */ + } else if (output_size >= *output_length) { + memcpy(output, temp_output_buffer, *output_length); + } else { + status = PSA_ERROR_BUFFER_TOO_SMALL; + } + +exit: + mbedtls_platform_zeroize(temp_output_buffer, sizeof(temp_output_buffer)); + return status; +} + +psa_status_t esp_crypto_aes_abort(esp_aes_operation_t *esp_aes_driver_ctx) +{ + esp_aes_context *ctx = (esp_aes_context *) esp_aes_driver_ctx->esp_aes_ctx; + if (ctx == NULL) { + return PSA_SUCCESS; + } + esp_aes_free(ctx); + free(ctx); + return PSA_SUCCESS; +} + +psa_status_t esp_crypto_aes_set_iv( + esp_aes_operation_t *esp_aes_driver_ctx, + const uint8_t *iv, size_t iv_length) +{ + if (iv_length != PSA_CIPHER_IV_LENGTH(PSA_KEY_TYPE_AES, esp_aes_driver_ctx->aes_alg)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + memcpy(esp_aes_driver_ctx->iv, iv, iv_length); + return PSA_SUCCESS; +} + + +static psa_status_t esp_crypto_aes_setup( + esp_aes_operation_t *esp_aes_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, psa_encrypt_or_decrypt_t mode) +{ + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + + if (!PSA_ALG_IS_CIPHER(alg)) { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } + + // if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) { + // status = PSA_ERROR_INVALID_ARGUMENT; + // goto exit; + // } + + switch (alg) { + case PSA_ALG_ECB_NO_PADDING: + case PSA_ALG_CBC_NO_PADDING: + case PSA_ALG_CBC_PKCS7: + case PSA_ALG_CTR: + case PSA_ALG_XTS: + case PSA_ALG_CFB: + case PSA_ALG_OFB: + break; + default: + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; + } + + esp_aes_context *ctx = (esp_aes_context *) malloc(sizeof(esp_aes_context)); + if (ctx == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto exit; + } + + esp_aes_init(ctx); + + status = mbedtls_to_psa_error(esp_aes_setkey(ctx, key_buffer, key_buffer_size * 8)); + + if (status != PSA_SUCCESS) { + free(ctx); + goto exit; + } + + esp_aes_driver_ctx->aes_alg = alg; + esp_aes_driver_ctx->mode = mode; + esp_aes_driver_ctx->esp_aes_ctx = (void *) ctx; + esp_aes_driver_ctx->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 : PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES)); +exit: + return status; +} + +psa_status_t esp_aes_cipher_encrypt_setup( + esp_aes_operation_t *esp_aes_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg) +{ + return esp_crypto_aes_setup(esp_aes_driver_ctx, attributes, + key_buffer, key_buffer_size, + alg, PSA_CRYPTO_DRIVER_ENCRYPT); +} + +psa_status_t esp_aes_cipher_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *iv, + size_t iv_length, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + esp_aes_operation_t esp_aes_driver_ctx; + memset(&esp_aes_driver_ctx, 0, sizeof(esp_aes_operation_t)); + size_t update_output_length, finish_output_length; + + // ESP_LOGI("esp_aes_cipher_encrypt", "Starting encryption"); + + status = esp_aes_cipher_encrypt_setup(&esp_aes_driver_ctx, attributes, + key_buffer, key_buffer_size, + alg); + if (status != PSA_SUCCESS) { + ESP_LOGE("esp_aes_cipher_encrypt", "Failed to setup encryption: %ld", status); + goto exit; + } + + if (iv_length > 0) { + status = esp_crypto_aes_set_iv(&esp_aes_driver_ctx, iv, iv_length); + if (status != PSA_SUCCESS) { + ESP_LOGE("esp_aes_cipher_encrypt", "Failed to set IV: %ld", status); + goto exit; + } + } + + status = esp_crypto_aes_update(&esp_aes_driver_ctx, input, input_length, + output, output_size, + &update_output_length); + if (status != PSA_SUCCESS) { + ESP_LOGE("esp_aes_cipher_encrypt", "Failed to update: %ld", status); + goto exit; + } + + status = esp_crypto_aes_finish(&esp_aes_driver_ctx, + mbedtls_buffer_offset(output, update_output_length), + output_size - update_output_length, &finish_output_length); + if (status != PSA_SUCCESS) { + ESP_LOGE("esp_aes_cipher_encrypt", "Failed to finish: %ld", status); + goto exit; + } + + *output_length = update_output_length + finish_output_length; + +exit: + if (status == PSA_SUCCESS) { + status = esp_crypto_aes_abort(&esp_aes_driver_ctx); + } else { + ESP_LOGE("esp_aes_cipher_encrypt", "Failed to abort: %ld", status); + esp_crypto_aes_abort(&esp_aes_driver_ctx); + } + + return status; +} + +psa_status_t esp_aes_cipher_decrypt_setup( + esp_aes_operation_t *esp_aes_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg) +{ + return esp_crypto_aes_setup(esp_aes_driver_ctx, attributes, + key_buffer, key_buffer_size, + alg, PSA_CRYPTO_DRIVER_DECRYPT); +} + +psa_status_t esp_aes_cipher_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key, size_t key_length, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, size_t *output_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + esp_aes_operation_t esp_aes_driver_ctx; + memset(&esp_aes_driver_ctx, 0, sizeof(esp_aes_operation_t)); + size_t olength, accumulated_length; + + status = esp_aes_cipher_decrypt_setup(&esp_aes_driver_ctx, attributes, + key, key_length, + alg); + if (status != PSA_SUCCESS) { + goto exit; + } + + uint8_t iv_length = PSA_CIPHER_IV_LENGTH(psa_get_key_type(attributes), alg); + + if (iv_length > 0) { + status = esp_crypto_aes_set_iv(&esp_aes_driver_ctx, + input, iv_length); + if (status != PSA_SUCCESS) { + goto exit; + } + } + + status = esp_crypto_aes_update(&esp_aes_driver_ctx, + mbedtls_buffer_offset_const(input, iv_length), + input_length - iv_length, + output, output_size, &olength); + if (status != PSA_SUCCESS) { + goto exit; + } + + accumulated_length = olength; + + status = esp_crypto_aes_finish(&esp_aes_driver_ctx, + mbedtls_buffer_offset(output, accumulated_length), + output_size - accumulated_length, &olength); + if (status != PSA_SUCCESS) { + goto exit; + } + + *output_length = accumulated_length + olength; + +exit: + if (status == PSA_SUCCESS) { + status = esp_crypto_aes_abort(&esp_aes_driver_ctx); + } else { + esp_crypto_aes_abort(&esp_aes_driver_ctx); + } + + // printf("AES decryption finished with status: %ld\n", status); + + return status; +} + +psa_status_t esp_aes_cipher_set_iv( + esp_aes_operation_t *operation, + const uint8_t *iv, + size_t iv_length) +{ + return esp_crypto_aes_set_iv(operation, iv, iv_length); +} + +psa_status_t esp_aes_cipher_update( + esp_aes_operation_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length) +{ + return esp_crypto_aes_update(operation, input, input_length, + output, output_size, output_length); +} + +psa_status_t esp_aes_cipher_finish( + esp_aes_operation_t *operation, + uint8_t *output, + size_t output_size, + size_t *output_length) +{ + return esp_crypto_aes_finish(operation, output, output_size, output_length); +} + +psa_status_t esp_aes_cipher_abort( + esp_aes_operation_t *operation) +{ + esp_aes_context *ctx = (esp_aes_context *) operation->esp_aes_ctx; + if (ctx == NULL) { + return PSA_SUCCESS; + } + esp_aes_free(ctx); + free(ctx); + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c new file mode 100644 index 00000000000..7ccf1b1dc98 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_aes_gcm.c @@ -0,0 +1,274 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "esp_log.h" +// #include "mbedtls/aes.h" +#include "psa_crypto_core.h" +// #include "mbedtls/cipher.h" + +#include "aes/esp_aes_gcm.h" +#include "psa_crypto_driver_esp_aes_gcm.h" +#include "../include/psa_crypto_driver_esp_aes_contexts.h" +// #ifdef ESP_MBEDTLS_AES_ACCEL + +#if (defined(ESP_AES_DRIVER_ENABLED) || defined(MBEDTLS_HARDWARE_GCM)) + +#define ESP_AES_GCM_TAG_LENGTH 16 + +static psa_status_t esp_crypto_aes_gcm_setup( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, psa_encrypt_or_decrypt_t mode) +{ + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + esp_gcm_context *ctx = NULL; + + if (alg != PSA_ALG_GCM) { + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; + } + + if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) { + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; + } + + ctx = (esp_gcm_context *) malloc(sizeof(esp_gcm_context)); + if (ctx == NULL) { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto exit; + } + + esp_aes_gcm_init(ctx); + + status = mbedtls_to_psa_error(esp_aes_gcm_setkey(ctx, 2, key_buffer, key_buffer_size * 8)); + + if (status != PSA_SUCCESS) { + free(ctx); + goto exit; + } + + esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx = (void *) ctx; + esp_aes_gcm_driver_ctx->mode = mode; + +exit: + return status; +} + +psa_status_t esp_crypto_aes_gcm_encrypt_setup( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg) +{ + return esp_crypto_aes_gcm_setup(esp_aes_gcm_driver_ctx, attributes, + key_buffer, key_buffer_size, + alg, PSA_CRYPTO_DRIVER_ENCRYPT); +} + +psa_status_t esp_crypto_aes_gcm_decrypt_setup( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg) +{ + return esp_crypto_aes_gcm_setup(esp_aes_gcm_driver_ctx, attributes, + key_buffer, key_buffer_size, + alg, PSA_CRYPTO_DRIVER_DECRYPT); +} + +psa_status_t esp_crypto_aes_gcm_set_nonce( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const uint8_t *nonce, + size_t nonce_length) +{ + esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx; + return mbedtls_to_psa_error(esp_aes_gcm_starts(ctx, esp_aes_gcm_driver_ctx->mode, nonce, nonce_length)); +} + +psa_status_t esp_crypto_aes_gcm_update_ad( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const uint8_t *aad, + size_t aad_length) +{ + esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx; + return mbedtls_to_psa_error(esp_aes_gcm_update_ad(ctx, aad, aad_length)); +} + +psa_status_t esp_crypto_aes_gcm_update( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length) +{ + size_t update_output_length = input_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx; + status = mbedtls_to_psa_error(esp_aes_gcm_update(ctx, input, input_length, output, output_size, &update_output_length)); + if (status == PSA_SUCCESS) { + *output_length = update_output_length; + } + return status; +} + +psa_status_t esp_crypto_aes_gcm_finish( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + uint8_t *output, + size_t output_size, + size_t *output_length, + uint8_t *tag, + size_t tag_size, + size_t *tag_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t finish_output_size = 0; + + if (tag_size < ESP_AES_GCM_TAG_LENGTH) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx; + status = mbedtls_to_psa_error(esp_aes_gcm_finish(ctx, output, output_size, output_length, tag, tag_size)); + if (status == PSA_SUCCESS) { + /* This will be zero for all supported algorithms currently, but left + * here for future support. */ + *output_length = finish_output_size; + *tag_length = ESP_AES_GCM_TAG_LENGTH; + } + return status; +} + +psa_status_t esp_crypto_aes_gcm_abort(esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx) +{ + esp_gcm_context *ctx = (esp_gcm_context *) esp_aes_gcm_driver_ctx->esp_aes_gcm_ctx; + if (ctx == NULL) { + return PSA_SUCCESS; + } + esp_aes_gcm_free(ctx); + free(ctx); + return PSA_SUCCESS; +} + +psa_status_t esp_crypto_aes_gcm_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length) +{ + uint8_t *tag = NULL; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + esp_aes_gcm_operation_t esp_aes_gcm_driver_ctx; + memset(&esp_aes_gcm_driver_ctx, 0, sizeof(esp_aes_gcm_operation_t)); + + status = esp_crypto_aes_gcm_encrypt_setup(&esp_aes_gcm_driver_ctx, attributes, + key_buffer, key_buffer_size, + alg); + if (status != PSA_SUCCESS) { + goto exit; + } + + /* For all currently supported modes, the tag is at the end of the + * ciphertext. */ + if (ciphertext_size < (plaintext_length + ESP_AES_GCM_TAG_LENGTH)) { + status = PSA_ERROR_BUFFER_TOO_SMALL; + goto exit; + } + tag = ciphertext + plaintext_length; + status = mbedtls_to_psa_error( + esp_aes_gcm_crypt_and_tag((esp_gcm_context *) esp_aes_gcm_driver_ctx.esp_aes_gcm_ctx, + PSA_CRYPTO_DRIVER_ENCRYPT, + plaintext_length, + nonce, nonce_length, + additional_data, additional_data_length, + plaintext, ciphertext, + ESP_AES_GCM_TAG_LENGTH, tag)); + + if (status == PSA_SUCCESS) { + *ciphertext_length = plaintext_length + ESP_AES_GCM_TAG_LENGTH; + } + +exit: + esp_crypto_aes_gcm_abort(&esp_aes_gcm_driver_ctx); + + return status; +} + +/* Locate the tag in a ciphertext buffer containing the encrypted data + * followed by the tag. Return the length of the part preceding the tag in + * *plaintext_length. This is the size of the plaintext in modes where + * the encrypted data has the same size as the plaintext, such as + * CCM and GCM. */ +static psa_status_t psa_aead_unpadded_locate_tag(size_t tag_length, + const uint8_t *ciphertext, + size_t ciphertext_length, + size_t plaintext_size, + const uint8_t **p_tag) +{ + size_t payload_length; + if (tag_length > ciphertext_length) { + return PSA_ERROR_INVALID_ARGUMENT; + } + payload_length = ciphertext_length - tag_length; + if (payload_length > plaintext_size) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + *p_tag = ciphertext + payload_length; + return PSA_SUCCESS; +} + +psa_status_t esp_crypto_aes_gcm_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + esp_aes_gcm_operation_t esp_aes_gcm_driver_ctx; + memset(&esp_aes_gcm_driver_ctx, 0, sizeof(esp_aes_gcm_operation_t)); + const uint8_t *tag = NULL; + + status = esp_crypto_aes_gcm_decrypt_setup(&esp_aes_gcm_driver_ctx, attributes, + key_buffer, key_buffer_size, + alg); + if (status != PSA_SUCCESS) { + goto exit; + } + + status = psa_aead_unpadded_locate_tag(ESP_AES_GCM_TAG_LENGTH, ciphertext, ciphertext_length, plaintext_size, &tag); + if (status != PSA_SUCCESS) { + goto exit; + } + + status = mbedtls_to_psa_error( + esp_aes_gcm_auth_decrypt((esp_gcm_context *) esp_aes_gcm_driver_ctx.esp_aes_gcm_ctx, + ciphertext_length - ESP_AES_GCM_TAG_LENGTH, + nonce, nonce_length, + additional_data, + additional_data_length, + tag, ESP_AES_GCM_TAG_LENGTH, + ciphertext, plaintext)); + + if (status == PSA_SUCCESS) { + *plaintext_length = ciphertext_length - ESP_AES_GCM_TAG_LENGTH; + } + +exit: + esp_crypto_aes_gcm_abort(&esp_aes_gcm_driver_ctx); + return status; +} +// #endif /* ESP_MBEDTLS_AES_ACCEL */ +#endif /* ESP_AES_DRIVER_ENABLED && MBEDTLS_HARDWARE_GCM */ diff --git a/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c new file mode 100644 index 00000000000..c75101e143c --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_aes/psa_crypto_driver_esp_cmac.c @@ -0,0 +1,598 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_cmac.h" +#include "psa_crypto_driver_esp_cmac_contexts.h" +#include "mbedtls/constant_time.h" + +#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 16 + +#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__) +#define MBEDTLS_IS_BIG_ENDIAN 1 +#else +#define MBEDTLS_IS_BIG_ENDIAN 0 +#endif + +#define MBEDTLS_BSWAP32 __builtin_bswap32 + +static inline uint32_t mbedtls_get_unaligned_uint32(const void *p) +{ + uint32_t r; +#if defined(UINT_UNALIGNED) + mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; + r = *p32; +#elif defined(UINT_UNALIGNED_STRUCT) + mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; + r = p32->x; +#else + memcpy(&r, p, sizeof(r)); +#endif + return r; +} + +static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x) +{ +#if defined(UINT_UNALIGNED) + mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; + *p32 = x; +#elif defined(UINT_UNALIGNED_STRUCT) + mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p; + p32->x = x; +#else + memcpy(p, &x, sizeof(x)); +#endif +} + +#define MBEDTLS_GET_UINT32_BE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ + ? mbedtls_get_unaligned_uint32((data) + (offset)) \ + : MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \ + ) + +#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \ + do { \ + mbedtls_put_unaligned_uint32((data) + (offset), \ + (MBEDTLS_IS_BIG_ENDIAN) \ + ? (uint32_t) (n) \ + : MBEDTLS_BSWAP32((uint32_t) (n))); \ + } while (0) + +psa_status_t esp_cmac_mac_abort(esp_cmac_operation_t *operation) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + status = psa_destroy_key(operation->key_id); + if (status != PSA_SUCCESS) { + return status; + } + + status = psa_cipher_abort(&operation->cipher_ctx); + if (status != PSA_SUCCESS) { + return status; + } + + mbedtls_platform_zeroize(&operation->cipher_ctx, sizeof(psa_cipher_operation_t)); + return status; +} + +static psa_status_t mac_init( + esp_cmac_operation_t *operation, + psa_algorithm_t alg) +{ + memset(operation, 0, sizeof(*operation)); + + return PSA_SUCCESS; +} + +static psa_status_t esp_cmac_setup_internal(esp_cmac_operation_t *cmac, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size) +{ + int status = PSA_ERROR_CORRUPTION_DETECTED; + +#if defined(PSA_WANT_KEY_TYPE_DES) + /* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept + * to do CMAC with pure DES, so return NOT_SUPPORTED here. */ + if (psa_get_key_type(attributes) == PSA_KEY_TYPE_DES && + (psa_get_key_bits(attributes) == 64 || + psa_get_key_bits(attributes) == 128)) { + return PSA_ERROR_NOT_SUPPORTED; + } +#endif + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_type_t key_type = psa_get_key_type(attributes); + size_t key_bits = psa_get_key_bits(attributes); + psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING; + + /* Set up key attributes for PSA import */ + psa_set_key_type(&key_attributes, key_type); + psa_set_key_bits(&key_attributes, key_bits); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&key_attributes, alg); + + /* Import key for cipher operations */ + status = psa_import_key(&key_attributes, key_buffer, key_buffer_size, &cmac->key_id); + if (status != PSA_SUCCESS) { + return status; + } + + status = psa_cipher_encrypt_setup(&cmac->cipher_ctx, cmac->key_id, alg); + if (status != 0) { + return status; + } + + cmac->unprocessed_len = 0; + cmac->cipher_block_length = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type); + + mbedtls_platform_zeroize(cmac->state, sizeof(cmac->state)); + mbedtls_platform_zeroize(cmac->unprocessed_block, sizeof(cmac->unprocessed_block)); + + return PSA_SUCCESS; +} + +static psa_status_t esp_cmac_mac_setup_cmac(esp_cmac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + status = mac_init(operation, alg); + if (status != PSA_SUCCESS) { + return status; + } + status = esp_cmac_setup_internal(operation, attributes, key_buffer, key_buffer_size); + + if (status != PSA_SUCCESS) { + esp_cmac_mac_abort(operation); + } + + return status; +} + +psa_status_t esp_cmac_mac_setup(esp_cmac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) { + status = esp_cmac_mac_setup_cmac(operation, attributes, key_buffer, key_buffer_size, alg); + operation->alg = alg; + } else if (PSA_ALG_IS_HMAC(alg)) { + psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(alg); + uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; + size_t i; + size_t hash_size = PSA_HASH_LENGTH(hash_alg); + size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg); + + /* Sanity checks on block_size, to guarantee that there won't be a buffer + * overflow below. This should never trigger if the hash algorithm + * is implemented correctly. */ + /* The size checks against the ipad and opad buffers cannot be written + * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )` + * because that triggers -Wlogical-op on GCC 7.3. */ + if (block_size > sizeof(ipad)) { + return PSA_ERROR_NOT_SUPPORTED; + } + if (block_size > sizeof(operation->opad)) { + return PSA_ERROR_NOT_SUPPORTED; + } + if (block_size < hash_size) { + return PSA_ERROR_NOT_SUPPORTED; + } + + if (key_buffer_size > block_size) { + status = esp_sha_hash_compute(hash_alg, key_buffer, key_buffer_size, + ipad, sizeof(ipad), &key_buffer_size); + if (status != PSA_SUCCESS) { + return status; + } + } + /* A 0-length key is not commonly used in HMAC when used as a MAC, + * but it is permitted. It is common when HMAC is used in HKDF, for + * example. Don't call `memcpy` in the 0-length because `key` could be + * an invalid pointer which would make the behavior undefined. */ + else if (key_buffer_size != 0) { + /* Additional safety check: ensure key fits in ipad buffer */ + if (key_buffer_size > sizeof(ipad)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + memcpy(ipad, key_buffer, key_buffer_size); + } + + /* ipad contains the key followed by garbage. Xor and fill with 0x36 + * to create the ipad value. */ + for (i = 0; i < key_buffer_size; i++) { + ipad[i] ^= 0x36; + } + memset(ipad + key_buffer_size, 0x36, block_size - key_buffer_size); + + /* Copy the key material from ipad to opad, flipping the requisite bits, + * and filling the rest of opad with the requisite constant. */ + for (i = 0; i < key_buffer_size; i++) { + operation->opad[i] = ipad[i] ^ 0x36 ^ 0x5C; + } + memset(operation->opad + key_buffer_size, 0x5C, block_size - key_buffer_size); + status = esp_sha_hash_setup(&operation->hmac_operation, hash_alg); + if (status != PSA_SUCCESS) { + return status; + } + + status = esp_sha_hash_update(&operation->hmac_operation, ipad, block_size); + if (status != PSA_SUCCESS) { + return status; + } + operation->alg = alg; + } else { + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + status = PSA_ERROR_NOT_SUPPORTED; + } + return status; +} + +static void xor_no_simd(unsigned char *output, const unsigned char *input1, const unsigned char *input2, size_t length) +{ + for (size_t i = 0; i < length; i++) { + output[i] = input1[i] ^ input2[i]; + } +} + +static psa_status_t esp_cmac_mac_update_internal(esp_cmac_operation_t *cmac, const uint8_t *data, size_t data_length) +{ + unsigned char *state = cmac->state; + int ret = 0; + size_t n, j, olen, block_size; + + if (cmac == NULL || data == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + block_size = cmac->cipher_block_length; + + /* Is there data still to process from the last call, that's greater in + * size than a block? */ + if (cmac->unprocessed_len > 0 && data_length > block_size - cmac->unprocessed_len) { + memcpy(&cmac->unprocessed_block[cmac->unprocessed_len], data, block_size - cmac->unprocessed_len); + xor_no_simd(state, cmac->unprocessed_block, state, block_size); + + if ((ret = psa_cipher_update(&cmac->cipher_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != 0) { + goto exit; + } + + data += block_size - cmac->unprocessed_len; + data_length -= block_size - cmac->unprocessed_len; + cmac->unprocessed_len = 0; + } + + /* n is the number of blocks including any final partial block */ + n = (data_length + block_size - 1) / block_size; + /* Iterate across the input data in block sized chunks, excluding any + * final partial or complete block */ + for (j = 1; j < n; j++) { + xor_no_simd(state, data, state, block_size); + if ((ret = psa_cipher_update(&cmac->cipher_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != 0) { + goto exit; + } + + data_length -= block_size; + data += block_size; + } + + /* If there is data left over that wasn't aligned to a block */ + if (data_length > 0) { + memcpy(&cmac->unprocessed_block[cmac->unprocessed_len], data, data_length); + cmac->unprocessed_len += data_length; + } + +exit: + return ret; + +} + +psa_status_t esp_cmac_mac_update(esp_cmac_operation_t *cmac, const uint8_t *data, size_t data_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if (PSA_ALG_FULL_LENGTH_MAC(cmac->alg) == PSA_ALG_CMAC) { + status = esp_cmac_mac_update_internal(cmac, data, data_length); + } else if (PSA_ALG_IS_HMAC(cmac->alg)) { + status = esp_sha_hash_update(&cmac->hmac_operation, data, data_length); + } else { + (void) cmac; + (void) data; + (void) data_length; + status = PSA_ERROR_NOT_SUPPORTED; + } + + return status; +} + +static inline unsigned mbedtls_ct_uint_if_else_0(uint32_t condition, unsigned if1) +{ + return (unsigned) (condition & if1); +} + +static int cmac_multiply_by_u(unsigned char *output, + const unsigned char *input, + size_t blocksize) +{ + const unsigned char R_128 = 0x87; + unsigned char R_n; + uint32_t overflow = 0x00; + int i; + + if (blocksize == PSA_AES_BLOCK_SIZE) { + R_n = R_128; + } +#if defined(PSA_WANT_KEY_TYPE_DES) + else if (blocksize == PSA_DES_BLOCK_SIZE) { + const unsigned char R_64 = 0x1B; + R_n = R_64; + } +#endif + else { + return PSA_ERROR_INVALID_ARGUMENT; + } + + for (i = (int) blocksize - 4; i >= 0; i -= 4) { + uint32_t i32 = MBEDTLS_GET_UINT32_BE(&input[i], 0); + uint32_t new_overflow = i32 >> 31; + i32 = (i32 << 1) | overflow; + MBEDTLS_PUT_UINT32_BE(i32, &output[i], 0); + overflow = new_overflow; + } + + unsigned char msb = (input[0] >> 7) & 1; + output[blocksize - 1] ^= (unsigned char)(msb * R_n); + + + return 0; +} + +static int cmac_generate_subkeys(psa_cipher_operation_t *ctx, size_t block_size, + unsigned char *K1, unsigned char *K2) +{ + int ret = PSA_ERROR_CORRUPTION_DETECTED; + unsigned char L[PSA_CMAC_MAX_BLOCK_SIZE]; + size_t olen; + + mbedtls_platform_zeroize(L, sizeof(L)); + + /* Calculate Ek(0) */ + if ((ret = psa_cipher_update(ctx, L, block_size, L, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != 0) { + goto exit; + } + + /* + * Generate K1 and K2 + */ + if ((ret = cmac_multiply_by_u(K1, L, block_size)) != 0) { + goto exit; + } + + if ((ret = cmac_multiply_by_u(K2, K1, block_size)) != 0) { + goto exit; + } + +exit: + mbedtls_platform_zeroize(L, sizeof(L)); + + return ret; +} + +static void cmac_pad(unsigned char padded_block[MBEDTLS_CMAC_MAX_BLOCK_SIZE], + size_t padded_block_len, + const unsigned char *last_block, + size_t last_block_len) +{ + size_t j; + + for (j = 0; j < padded_block_len; j++) { + if (j < last_block_len) { + padded_block[j] = last_block[j]; + } else if (j == last_block_len) { + padded_block[j] = 0x80; + } else { + padded_block[j] = 0x00; + } + } +} + +static psa_status_t esp_cmac_mac_finish_internal( + esp_cmac_operation_t *cmac, + uint8_t *mac, + size_t mac_size, + size_t *mac_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t olen, block_size; + + unsigned char *state, *last_block; + unsigned char K1[PSA_CMAC_MAX_BLOCK_SIZE]; + unsigned char K2[PSA_CMAC_MAX_BLOCK_SIZE]; + unsigned char M_last[PSA_CMAC_MAX_BLOCK_SIZE]; + + if (cmac == NULL || mac == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + state = cmac->state; + block_size = cmac->cipher_block_length; + + mbedtls_platform_zeroize(K1, sizeof(K1)); + mbedtls_platform_zeroize(K2, sizeof(K2)); + cmac_generate_subkeys(&cmac->cipher_ctx, block_size, K1, K2); + + last_block = cmac->unprocessed_block; + + /* Calculate last block */ + if (cmac->unprocessed_len < block_size) { + cmac_pad(M_last, block_size, last_block, cmac->unprocessed_len); + xor_no_simd(M_last, M_last, K2, block_size); + } else { + /* Last block is complete block */ + xor_no_simd(M_last, last_block, K1, block_size); + } + + xor_no_simd(state, M_last, state, block_size); + if ((status = psa_cipher_update(&cmac->cipher_ctx, state, block_size, state, PSA_CMAC_MAX_BLOCK_SIZE, &olen)) != 0) { + goto exit; + } + + /* CMAC output is always the cipher block size, regardless of requested mac_size */ + size_t output_length = (mac_size < block_size) ? mac_size : block_size; + memcpy(mac, state, output_length); + *mac_length = output_length; +exit: + mbedtls_platform_zeroize(K1, sizeof(K1)); + mbedtls_platform_zeroize(K2, sizeof(K2)); + + cmac->unprocessed_len = 0; + mbedtls_platform_zeroize(cmac->unprocessed_block, sizeof(cmac->unprocessed_block)); + mbedtls_platform_zeroize(state, PSA_CMAC_MAX_BLOCK_SIZE); + + return status; +} + +psa_status_t esp_cmac_mac_finish( + esp_cmac_operation_t *cmac, + uint8_t *mac, + size_t mac_size, + size_t *mac_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if (PSA_ALG_FULL_LENGTH_MAC(cmac->alg) == PSA_ALG_CMAC) { + status = esp_cmac_mac_finish_internal(cmac, mac, mac_size, mac_length); + } else if (PSA_ALG_IS_HMAC(cmac->alg)) { + psa_algorithm_t hash_alg = PSA_ALG_GET_HASH(cmac->alg); + + uint8_t tmp[PSA_HASH_MAX_SIZE]; + size_t hash_size = 0; + size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg); + + status = esp_sha_hash_finish(&cmac->hmac_operation, tmp, sizeof(tmp), &hash_size); + if (status != PSA_SUCCESS) { + return status; + } + /* From here on, tmp needs to be wiped. */ + + status = esp_sha_hash_setup(&cmac->hmac_operation, hash_alg); + if (status != PSA_SUCCESS) { + goto exit; + } + + status = esp_sha_hash_update(&cmac->hmac_operation, cmac->opad, block_size); + if (status != PSA_SUCCESS) { + goto exit; + } + + status = esp_sha_hash_update(&cmac->hmac_operation, tmp, hash_size); + if (status != PSA_SUCCESS) { + goto exit; + } + + status = esp_sha_hash_finish(&cmac->hmac_operation, tmp, sizeof(tmp), &hash_size); + if (status != PSA_SUCCESS) { + goto exit; + } + + memcpy(mac, tmp, mac_size); + + *mac_length = mac_size; +exit: + mbedtls_platform_zeroize(tmp, hash_size); + } else { + (void) cmac; + (void) mac; + (void) mac_length; + (void) mac_size; + status = PSA_ERROR_NOT_SUPPORTED; + } + return status; +} + +psa_status_t esp_cmac_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + esp_cmac_operation_t operation = {0}; + + memset(&operation, 0, sizeof(operation)); + + status = esp_cmac_mac_setup(&operation, + attributes, key_buffer, key_buffer_size, + alg); + if (status != PSA_SUCCESS) { + goto exit; + } + + if (input_length > 0) { + status = esp_cmac_mac_update(&operation, input, input_length); + if (status != PSA_SUCCESS) { + goto exit; + } + } + size_t actual_mac_length = 0; + status = esp_cmac_mac_finish(&operation, mac, mac_size, &actual_mac_length); + if (status == PSA_SUCCESS) { + *mac_length = actual_mac_length; + } + +exit: + esp_cmac_mac_abort(&operation); + + return status; + +} + +psa_status_t esp_cmac_mac_verify_finish( + esp_cmac_operation_t *operation, + const uint8_t *mac, + size_t mac_length) +{ + uint8_t actual_mac[PSA_MAC_MAX_SIZE]; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if (operation == NULL || mac == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + if (mac_length > sizeof(actual_mac)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + + size_t actual_mac_length = 0; + + status = esp_cmac_mac_finish(operation, actual_mac, sizeof(actual_mac), &actual_mac_length); + if (status == PSA_SUCCESS) { + if (memcmp(actual_mac, mac, mac_length) == 0) { + return PSA_SUCCESS; + } else { + return PSA_ERROR_INVALID_SIGNATURE; + } + } + + return status; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c new file mode 100644 index 00000000000..5e7102ac828 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha1.c @@ -0,0 +1,440 @@ +/* + * SHA-1 implementation with hardware ESP support added. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include +#include "mbedtls/esp_config.h" +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha1.h" +#include "esp_sha_internal.h" +#include "sha/sha_core.h" +#include "esp_err.h" +#include "soc/soc_caps.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, + 0, 0, 0, 0, 0, 0, 0, 0, 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_starts(esp_sha1_context *ctx) { + memset(ctx, 0, sizeof(esp_sha1_context)); + 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); + + 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); + } +} + +#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; + 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) { +#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 + 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(); +#else + esp_sha1_software_process(ctx, input); +#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1 + } + + if (ilen > 0) { + memcpy((void *) (ctx->buffer + left), input + len, ilen - len); + } + return 0; +} + +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; +} + +psa_status_t esp_sha1_driver_abort(esp_sha1_context *ctx) +{ + if (!ctx) { + return PSA_ERROR_INVALID_ARGUMENT; + } + 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)); + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c new file mode 100644 index 00000000000..434023b127a --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha256.c @@ -0,0 +1,274 @@ +/* + * SHA-256 implementation with hardware ESP support added. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include +#include "mbedtls/esp_config.h" +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha256.h" +#include "esp_sha_internal.h" +#include "sha/sha_core.h" +#include "esp_err.h" +#include "soc/soc_caps.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 +}; + +psa_status_t 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 PSA_SUCCESS; +} + +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 +#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_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 SOC_SHA_SUPPORT_SHA224 + if (sha_type == ESP_SHA_OPERATION_TYPE_SHA224) { + *hash_length = PSA_HASH_LENGTH(PSA_ALG_SHA_224); + } else +#endif // SOC_SHA_SUPPORT_SHA224 + 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; +} + +psa_status_t esp_sha256_driver_abort(esp_sha256_context *ctx) +{ + if (!ctx) { + return PSA_ERROR_INVALID_ARGUMENT; + } + 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)); + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/sha/core/esp_sha512.c b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c similarity index 54% rename from components/mbedtls/port/sha/core/esp_sha512.c rename to components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c index 0c9e6607de9..b1078efab0b 100644 --- a/components/mbedtls/port/sha/core/esp_sha512.c +++ b/components/mbedtls/port/psa_driver/esp_sha/core/psa_crypto_driver_esp_sha512.c @@ -5,55 +5,22 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2025 Espressif Systems (Shanghai) CO LTD - */ -/* - * The SHA-512 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD */ -#include - -#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT) - -#include "mbedtls/sha512.h" - -#if defined(_MSC_VER) || defined(__WATCOMC__) -#define UL64(x) x##ui64 -#else -#define UL64(x) x##ULL -#endif - -#include -#include -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else #include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - +#include +#include "mbedtls/esp_config.h" +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha512.h" #include "esp_sha_internal.h" #include "sha/sha_core.h" -#include "esp_compiler.h" +#include "esp_err.h" +#include "sdkconfig.h" +#include "soc/soc_caps.h" -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize(void *v, size_t n) -{ - volatile unsigned char *p = v; - while (n--) { - *p++ = 0; - } -} +#if CONFIG_SOC_SHA_SUPPORT_SHA512 -/* - * 64-bit integer manipulation macros (big endian) - */ #ifndef PUT_UINT64_BE #define PUT_UINT64_BE(n,b,i) \ { \ @@ -68,64 +35,24 @@ static void mbedtls_zeroize(void *v, size_t n) } #endif /* PUT_UINT64_BE */ -void esp_sha512_set_mode(mbedtls_sha512_context *ctx, esp_sha_type type) -{ - switch (type) { - case SHA2_384: - case SHA2_512224: - case SHA2_512256: - case SHA2_512T: - ctx->mode = type; - break; - default: - ctx->mode = SHA2_512; - break; - } +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 +}; + +psa_status_t esp_sha512_starts(esp_sha512_context *ctx, int mode) { + memset(ctx, 0, sizeof(esp_sha512_context)); + ctx->mode = mode; + return PSA_SUCCESS; } -/* For SHA512/t mode the initial hash value will depend on t */ -void esp_sha512_set_t(mbedtls_sha512_context *ctx, uint16_t t_val) -{ - ctx->t_val = t_val; -} - -void mbedtls_sha512_init(mbedtls_sha512_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_sha512_context)); -} - -void mbedtls_sha512_free(mbedtls_sha512_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_zeroize(ctx, sizeof(mbedtls_sha512_context)); -} - -void mbedtls_sha512_clone(mbedtls_sha512_context *dst, - const mbedtls_sha512_context *src) -{ - memcpy(dst, src, sizeof(mbedtls_sha512_context)); -} - -/* - * SHA-512 context setup - */ -int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384) -{ - mbedtls_zeroize(ctx, sizeof(mbedtls_sha512_context)); - - if (is384) { - ctx->mode = SHA2_384; - } else { - ctx->mode = SHA2_512; - } - - return 0; -} - -static int esp_internal_sha_update_state(mbedtls_sha512_context *ctx) +static int esp_internal_sha_update_state(esp_sha512_context *ctx) { if (ctx->sha_state == ESP_SHA512_STATE_INIT) { if (ctx->mode == SHA2_512T) { @@ -146,7 +73,7 @@ static int esp_internal_sha_update_state(mbedtls_sha512_context *ctx) return 0; } -static void esp_internal_sha512_block_process(mbedtls_sha512_context *ctx, const uint8_t *data) +static void esp_internal_sha512_block_process(esp_sha512_context *ctx, const uint8_t *data) { esp_sha_block(ctx->mode, data, ctx->first_block); @@ -155,43 +82,8 @@ static void esp_internal_sha512_block_process(mbedtls_sha512_context *ctx, const } } -int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx, const unsigned char data[128]) -{ - int ret = -1; - - esp_sha_acquire_hardware(); - - esp_sha_set_mode(ctx->mode); - - ret = esp_internal_sha_update_state(ctx); - if (ret != 0) { - esp_sha_release_hardware(); - return ret; - } - -#if SOC_SHA_SUPPORT_DMA - // Likely to use DMA because data size is 128 bytes which is larger or equal to the DMA threshold - if (likely(sha_operation_mode(128) == SHA_DMA_MODE)) { - ret = esp_sha_dma(ctx->mode, data, 128, NULL, 0, ctx->first_block); - if (ret != 0) { - esp_sha_release_hardware(); - return ret; - } - } else -#endif /* SOC_SHA_SUPPORT_DMA */ - { - esp_sha_block(ctx->mode, data, ctx->first_block); - } - - esp_sha_read_digest_state(ctx->mode, ctx->state); - esp_sha_release_hardware(); - return ret; -} - -/* - * SHA-512 process buffer - */ -int mbedtls_sha512_update(mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen) +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; @@ -204,7 +96,6 @@ int mbedtls_sha512_update(mbedtls_sha512_context *ctx, const unsigned char *inpu fill = 128 - left; ctx->total[0] += (uint64_t) ilen; - if (ctx->total[0] < (uint64_t) ilen) { ctx->total[1]++; } @@ -267,21 +158,7 @@ int mbedtls_sha512_update(mbedtls_sha512_context *ctx, const unsigned char *inpu 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 -}; - -/* - * SHA-512 final digest - */ -int mbedtls_sha512_finish(mbedtls_sha512_context *ctx, unsigned char *output) +static int esp_sha512_finish(esp_sha512_context *ctx, unsigned char *output) { int ret = -1; size_t last, padn; @@ -298,21 +175,128 @@ int mbedtls_sha512_finish(mbedtls_sha512_context *ctx, unsigned char *output) last = (size_t)(ctx->total[0] & 0x7F); padn = (last < 112) ? (112 - last) : (240 - last); - if ((ret = mbedtls_sha512_update(ctx, sha512_padding, padn)) != 0) { + if ((ret = esp_sha512_update(ctx, sha512_padding, padn)) != 0) { return ret; } - if ((ret = mbedtls_sha512_update(ctx, msglen, 16)) != 0) { + if ((ret = esp_sha512_update(ctx, msglen, 16)) != 0) { return ret; } +#if SOC_SHA_SUPPORT_SHA384 if (ctx->mode == SHA2_384) { memcpy(output, ctx->state, 48); - } else { + } else +#endif // SOC_SHA_SUPPORT_SHA384 + { memcpy(output, ctx->state, 64); } return ret; } -#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */ +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) +{ + 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 = SHA2_512; +#if SOC_SHA_SUPPORT_SHA384 + mode = (alg == PSA_ALG_SHA_384) ? SHA2_384 : SHA2_512; +#endif // SOC_SHA_SUPPORT_SHA384 + 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; +} + +psa_status_t esp_sha512_driver_abort(esp_sha512_context *ctx) +{ + if (!ctx) { + return PSA_ERROR_INVALID_ARGUMENT; + } + memset(ctx, 0, sizeof(esp_sha512_context)); + return PSA_SUCCESS; +} + +psa_status_t esp_sha512_driver_clone(const esp_sha512_context *source_ctx, esp_sha512_context *target_ctx) +{ + if (source_ctx == NULL || target_ctx == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + memcpy(target_ctx, source_ctx, sizeof(esp_sha512_context)); + return PSA_SUCCESS; +} + +#endif // SOC_SHA_SUPPORT_SHA512 diff --git a/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha1.h b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha1.h new file mode 100644 index 00000000000..954ae7c3ab8 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha1.h @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#pragma once + +#include +#include + +/* Forward declarations to avoid circular dependencies */ +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); + +int esp_sha1_starts(esp_sha1_context *ctx); + +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); + +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); diff --git a/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha256.h b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha256.h new file mode 100644 index 00000000000..bb55425054c --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha256.h @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#pragma once + +#if defined(ESP_SHA_DRIVER_ENABLED) + +#include +#include + +/* Forward declarations to avoid circular dependencies */ +typedef uint32_t psa_algorithm_t; +typedef int32_t psa_status_t; + +psa_status_t esp_sha256_starts(esp_sha256_context *ctx, int is224); + +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); + +psa_status_t esp_sha256_driver_abort(esp_sha256_context *ctx); + +psa_status_t esp_sha256_driver_clone(const esp_sha256_context *source_ctx, esp_sha256_context *target_ctx); +#endif /* ESP_SHA_DRIVER_ENABLED */ diff --git a/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha512.h b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha512.h new file mode 100644 index 00000000000..99346a97d36 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/include/psa_crypto_driver_esp_sha512.h @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#pragma once + +#if defined(ESP_SHA_DRIVER_ENABLED) + +#include +#include + +/* Forward declarations to avoid circular dependencies */ +typedef 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_starts(esp_sha512_context *ctx, int mode); + +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); + +psa_status_t esp_sha512_driver_abort(esp_sha512_context *ctx); + +psa_status_t esp_sha512_driver_clone(const esp_sha512_context *source_ctx, esp_sha512_context *target_ctx); +#endif /* ESP_SHA_DRIVER_ENABLED */ diff --git a/components/mbedtls/port/sha/parallel_engine/esp_sha1.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c similarity index 63% rename from components/mbedtls/port/sha/parallel_engine/esp_sha1.c rename to components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c index cd38987e601..160ff865598 100644 --- a/components/mbedtls/port/sha/parallel_engine/esp_sha1.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha1.c @@ -1,51 +1,19 @@ /* - * SHA-1 implementation with hardware ESP32 support added. - * Uses mbedTLS software implementation for failover when concurrent - * SHA operations are in use. + * SHA-1 implementation with hardware ESP support added. * * SPDX-FileCopyrightText: The Mbed TLS Contributors * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#include - -#if defined(MBEDTLS_SHA1_ALT) - -#include "mbedtls/sha1.h" #include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - +#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" -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) -{ - volatile unsigned char *p = (unsigned char *)v; - while ( n-- ) { - *p++ = 0; - } -} - -/* - * 32-bit integer manipulation macros (big endian) - */ #ifndef GET_UINT32_BE #define GET_UINT32_BE(n,b,i) \ { \ @@ -66,43 +34,28 @@ static void mbedtls_zeroize( void *v, size_t n ) } #endif -void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) +psa_status_t esp_sha1_driver_clone(const esp_sha1_context *source_ctx, esp_sha1_context *target_ctx) { - memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); + 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; } -void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) -{ - if ( ctx == NULL ) { - return; - } - - if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { - esp_sha_unlock_engine(SHA1); - } - mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); -} - -void mbedtls_sha1_clone( mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src ) -{ - *dst = *src; - - if (src->mode == ESP_MBEDTLS_SHA1_HARDWARE) { - /* Copy hardware digest state out to cloned state, - which will be a software digest. - */ - esp_sha_read_digest_state(SHA1, dst->state); - dst->mode = ESP_MBEDTLS_SHA1_SOFTWARE; - } -} - - -/* - * SHA-1 context setup - */ -int mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) +int esp_sha1_starts(esp_sha1_context *ctx) { + memset(ctx, 0, sizeof(esp_sha1_context)); ctx->total[0] = 0; ctx->total[1] = 0; @@ -112,16 +65,17 @@ int mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) ctx->state[3] = 0x10325476; ctx->state[4] = 0xC3D2E1F0; - if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { +#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1 + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_unlock_engine(SHA1); } - ctx->mode = ESP_MBEDTLS_SHA1_UNUSED; +#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1 + ctx->operation_mode = ESP_SHA_MODE_UNUSED; - return 0; + return ESP_OK; } - -static void mbedtls_sha1_software_process( mbedtls_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; @@ -277,44 +231,42 @@ static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsi ctx->state[4] += E; } - -static int esp_internal_sha1_parallel_engine_process( mbedtls_sha1_context *ctx, const unsigned char data[64], bool read_digest ) +static int esp_internal_sha1_parallel_engine_process( esp_sha1_context *ctx, const unsigned char data[64], bool read_digest ) { +#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1 bool first_block = false; - if (ctx->mode == ESP_MBEDTLS_SHA1_UNUSED) { + if (ctx->operation_mode == ESP_SHA_MODE_UNUSED) { /* try to use hardware for this digest */ if (esp_sha_try_lock_engine(SHA1)) { - ctx->mode = ESP_MBEDTLS_SHA1_HARDWARE; + ctx->operation_mode = ESP_SHA_MODE_HARDWARE; first_block = true; } else { - ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE; + ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; } } - if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_block(SHA1, data, first_block); if (read_digest) { esp_sha_read_digest_state(SHA1, ctx->state); } } else { - mbedtls_sha1_software_process(ctx, data); + esp_sha1_software_process(ctx, data); } - +#else + esp_sha1_software_process(ctx, data); +#endif return 0; } - -int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) +int esp_internal_sha1_process( esp_sha1_context *ctx, const unsigned char data[64] ) { return esp_internal_sha1_parallel_engine_process(ctx, data, true); } -/* - * SHA-1 process buffer - */ -int mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) +int esp_sha1_update(esp_sha1_context *ctx, const unsigned char *input, size_t ilen) { int ret = -1; size_t fill; @@ -355,9 +307,11 @@ int mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, ilen -= 64; } - if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { +#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 ); @@ -373,10 +327,7 @@ static const unsigned char sha1_padding[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -/* -* SHA-1 final digest - */ -int mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) +int esp_sha1_finish(esp_sha1_context *ctx, uint8_t *output) { int ret = -1; uint32_t last, padn; @@ -393,17 +344,18 @@ int mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - if ( ( ret = mbedtls_sha1_update( ctx, sha1_padding, padn ) ) != 0 ) { + if ((ret = esp_sha1_update(ctx, sha1_padding, padn)) != 0) { goto out; } - if ( ( ret = mbedtls_sha1_update( ctx, msglen, 8 ) ) != 0 ) { + if ((ret = esp_sha1_update(ctx, msglen, 8)) != 0) { goto out; } - /* if state is in hardware, read it out */ - if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { +#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 ); @@ -412,12 +364,94 @@ int mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) PUT_UINT32_BE( ctx->state[4], output, 16 ); out: - if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) { +#ifdef MBEDTLS_PSA_ACCEL_ALG_SHA_1 + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_unlock_engine(SHA1); - ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE; + ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; } - +#endif // MBEDTLS_PSA_ACCEL_ALG_SHA_1 return ret; } -#endif /* MBEDTLS_SHA1_ALT */ +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; +} + +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_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; +} diff --git a/components/mbedtls/port/sha/parallel_engine/esp_sha256.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c similarity index 60% rename from components/mbedtls/port/sha/parallel_engine/esp_sha256.c rename to components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c index 10f6f22feab..4d99864dfe9 100644 --- a/components/mbedtls/port/sha/parallel_engine/esp_sha256.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha256.c @@ -1,47 +1,19 @@ /* - * SHA-256 implementation with hardware ESP32 support added. - * Uses mbedTLS software implementation for failover when concurrent - * SHA operations are in use. + * SHA-256 implementation with hardware ESP support added. * * SPDX-FileCopyrightText: The Mbed TLS Contributors * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD */ -/* - * The SHA-256 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ - -#include - -#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT) - -#include "mbedtls/sha256.h" #include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha256.h" #include "sha/sha_parallel_engine.h" - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) -{ - volatile unsigned char *p = v; - while ( n-- ) { - *p++ = 0; - } -} +#include "esp_err.h" +#include "soc/soc_caps.h" /* * 32-bit integer manipulation macros (big endian) @@ -66,46 +38,28 @@ do { \ } while( 0 ) #endif -void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) +psa_status_t esp_sha256_driver_clone(const esp_sha256_context *source_ctx, esp_sha256_context *target_ctx) { - memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); + 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; } -void mbedtls_sha256_free( mbedtls_sha256_context *ctx ) -{ - if ( ctx == NULL ) { - return; - } - - if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { - esp_sha_unlock_engine(SHA2_256); - } - mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); -} - -void mbedtls_sha256_clone( mbedtls_sha256_context *dst, - const mbedtls_sha256_context *src ) -{ - *dst = *src; - - if (src->mode == ESP_MBEDTLS_SHA256_HARDWARE) { - /* Copy hardware digest state out to cloned state, - which will become a software digest. - */ - esp_sha_read_digest_state(SHA2_256, dst->state); - dst->mode = ESP_MBEDTLS_SHA256_SOFTWARE; - } -} - -/* - * SHA-256 context setup - */ -int mbedtls_sha256_starts( mbedtls_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; - if ( is224 == 0 ) { + if ( mode == SHA2_256 ) { /* SHA-256 */ ctx->state[0] = 0x6A09E667; ctx->state[1] = 0xBB67AE85; @@ -127,12 +81,12 @@ int mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 ) ctx->state[7] = 0xBEFA4FA4; } - ctx->is224 = is224; - if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { + ctx->mode = mode; + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_unlock_engine(SHA2_256); } - ctx->mode = ESP_MBEDTLS_SHA256_UNUSED; - return 0; + ctx->operation_mode = ESP_SHA_MODE_UNUSED; + return PSA_SUCCESS; } static const uint32_t K[] = { @@ -179,12 +133,11 @@ static const uint32_t K[] = { d += temp1; h = temp1 + temp2; \ } - -static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) +static void esp_sha256_software_process(esp_sha256_context *ctx, const unsigned char data[64]) { - uint32_t temp1, temp2, W[64]; - uint32_t A[8]; - unsigned int i; + uint32_t temp1, temp2, W[64] = {0}; + uint32_t A[8] = {0}; + unsigned int i = 0; for ( i = 0; i < 8; i++ ) { A[i] = ctx->state[i]; @@ -235,46 +188,43 @@ static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const ctx->state[i] += A[i]; } } - - -static int esp_internal_sha256_parallel_engine_process( mbedtls_sha256_context *ctx, const unsigned char data[64], bool read_digest ) +static int esp_internal_sha256_parallel_engine_process(esp_sha256_context *ctx, const unsigned char data[64], bool read_digest) { bool first_block = false; - if (ctx->mode == ESP_MBEDTLS_SHA256_UNUSED) { + if (ctx->operation_mode == ESP_SHA_MODE_UNUSED) { /* try to use hardware for this digest */ - if (!ctx->is224 && esp_sha_try_lock_engine(SHA2_256)) { - ctx->mode = ESP_MBEDTLS_SHA256_HARDWARE; + 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->mode = ESP_MBEDTLS_SHA256_SOFTWARE; + ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; } } - if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_block(SHA2_256, data, first_block); if (read_digest) { esp_sha_read_digest_state(SHA2_256, ctx->state); } } else { - mbedtls_sha256_software_process(ctx, data); + esp_sha256_software_process(ctx, data); } return 0; } - -int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) +int esp_internal_sha256_process( esp_sha256_context *ctx, const unsigned char data[64] ) { return esp_internal_sha256_parallel_engine_process(ctx, data, true); } - -/* - * SHA-256 process buffer - */ -int mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input, - size_t ilen ) +static int esp_sha256_update(esp_sha256_context *ctx, const unsigned char *input, + size_t ilen) { int ret = -1; size_t fill; @@ -315,7 +265,7 @@ int mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *inp ilen -= 64; } - if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_read_digest_state(SHA2_256, ctx->state); } @@ -333,10 +283,7 @@ static const unsigned char sha256_padding[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -/* - * SHA-256 final digest - */ -int mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char *output ) +static int esp_sha256_finish(esp_sha256_context *ctx, unsigned char *output) { int ret = -1; uint32_t last, padn; @@ -353,16 +300,15 @@ int mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char *output ) last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - if ( ( ret = mbedtls_sha256_update( ctx, sha256_padding, padn ) ) != 0 ) { + if ( ( ret = esp_sha256_update( ctx, sha256_padding, padn ) ) != 0 ) { goto out; } - if ( ( ret = mbedtls_sha256_update( ctx, msglen, 8 ) ) != 0 ) { + if ( ( ret = esp_sha256_update( ctx, msglen, 8 ) ) != 0 ) { goto out; } - /* if state is in hardware, read it out */ - if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_read_digest_state(SHA2_256, ctx->state); } @@ -373,18 +319,117 @@ int mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char *output ) 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 ); - if ( ctx->is224 == 0 ) { - PUT_UINT32_BE( ctx->state[7], output, 28 ); - } out: - if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) { + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_unlock_engine(SHA2_256); - ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE; + ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; } - return ret; } -#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */ +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, + 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; +} + +psa_status_t esp_sha256_driver_abort(esp_sha256_context *ctx) +{ + if (!ctx) { + return PSA_ERROR_INVALID_ARGUMENT; + } + // Also unlock the hardware engine if it was in use + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { + esp_sha_unlock_engine(SHA2_256); + ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; + } + memset(ctx, 0, sizeof(esp_sha256_context)); + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/sha/parallel_engine/esp_sha512.c b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c similarity index 65% rename from components/mbedtls/port/sha/parallel_engine/esp_sha512.c rename to components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c index b305cdf16e1..c621f51980e 100644 --- a/components/mbedtls/port/sha/parallel_engine/esp_sha512.c +++ b/components/mbedtls/port/psa_driver/esp_sha/parallel_engine/psa_crypto_driver_esp_sha512.c @@ -1,25 +1,19 @@ /* - * SHA-512 implementation with hardware ESP32 support added. - * Uses mbedTLS software implementation for failover when concurrent - * SHA operations are in use. + * SHA-512 implementation with hardware ESP support added. * * SPDX-FileCopyrightText: The Mbed TLS Contributors * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD - */ -/* - * The SHA-512 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + * SPDX-FileContributor: 2025 Espressif Systems (Shanghai) CO LTD */ -#include - -#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT) - -#include "mbedtls/sha512.h" +#include +#include "psa_crypto_driver_esp_sha.h" +#include "../include/psa_crypto_driver_esp_sha512.h" +#include "sha/sha_parallel_engine.h" +#include "esp_err.h" +#include "soc/soc_caps.h" #if defined(_MSC_VER) || defined(__WATCOMC__) #define UL64(x) x##ui64 @@ -27,33 +21,6 @@ #define UL64(x) x##ULL #endif -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#include "sha/sha_parallel_engine.h" - -inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx) -{ - return ctx->is384 ? SHA2_384 : SHA2_512; -} - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) -{ - volatile unsigned char *p = v; - while ( n-- ) { - *p++ = 0; - } -} - /* * 64-bit integer manipulation macros (big endian) */ @@ -85,51 +52,18 @@ static void mbedtls_zeroize( void *v, size_t n ) } #endif /* PUT_UINT64_BE */ -void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) +inline static esp_sha_type sha_type(const esp_sha512_context *ctx) { - memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); + return ctx->mode; } -void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) -{ - if ( ctx == NULL ) { - return; - } - - if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { - esp_sha_unlock_engine(sha_type(ctx)); - } - mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); -} - -void mbedtls_sha512_clone( mbedtls_sha512_context *dst, - const mbedtls_sha512_context *src ) -{ - *dst = *src; - - if (src->mode == ESP_MBEDTLS_SHA512_HARDWARE) { - /* Copy hardware digest state out to cloned state, - which will be a software digest. - - Always read 512 bits of state, even for SHA-384 - (SHA-384 state is identical to SHA-512, only - digest is truncated.) - */ - esp_sha_read_digest_state(SHA2_512, dst->state); - dst->mode = ESP_MBEDTLS_SHA512_SOFTWARE; - } -} - - -/* - * SHA-512 context setup - */ -int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 ) +psa_status_t 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 ( is384 == 0 ) { + if ( mode == SHA2_512 ) { /* SHA-512 */ ctx->state[0] = UL64(0x6A09E667F3BCC908); ctx->state[1] = UL64(0xBB67AE8584CAA73B); @@ -151,13 +85,14 @@ int mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 ) ctx->state[7] = UL64(0x47B5481DBEFA4FA4); } - ctx->is384 = is384; - if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { + ctx->mode = mode; + + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_unlock_engine(sha_type(ctx)); } - ctx->mode = ESP_MBEDTLS_SHA512_UNUSED; + ctx->operation_mode = ESP_SHA_MODE_UNUSED; - return 0; + return PSA_SUCCESS; } /* @@ -207,7 +142,7 @@ static const uint64_t K[80] = { }; -static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) +static void esp_sha512_software_process(esp_sha512_context *ctx, const unsigned char data[128]) { int i; uint64_t temp1, temp2, W[80]; @@ -272,45 +207,38 @@ static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const ctx->state[7] += H; } - -static int esp_internal_sha512_parallel_engine_process( mbedtls_sha512_context *ctx, const unsigned char data[128], bool read_digest ) +static int esp_internal_sha512_parallel_engine_process( esp_sha512_context *ctx, const unsigned char data[128], bool read_digest ) { bool first_block = false; - if (ctx->mode == ESP_MBEDTLS_SHA512_UNUSED) { + if (ctx->mode == ESP_SHA_MODE_UNUSED) { /* try to use hardware for this digest */ if (esp_sha_try_lock_engine(sha_type(ctx))) { - ctx->mode = ESP_MBEDTLS_SHA512_HARDWARE; + ctx->mode = ESP_SHA_MODE_HARDWARE; first_block = true; } else { - ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE; + ctx->mode = ESP_SHA_MODE_SOFTWARE; } } - if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { + 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 { - mbedtls_sha512_software_process(ctx, data); + esp_sha512_software_process(ctx, data); } return 0; } - -int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) +int esp_internal_sha512_process( esp_sha512_context *ctx, const unsigned char data[128] ) { return esp_internal_sha512_parallel_engine_process(ctx, data, true); } - - -/* - * SHA-512 process buffer - */ -int mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input, - size_t ilen ) +static int esp_sha512_update(esp_sha512_context *ctx, const unsigned char *input, + size_t ilen) { int ret = -1; size_t fill; @@ -349,7 +277,7 @@ int mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *inp ilen -= 128; } - if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_read_digest_state(sha_type(ctx), ctx->state); } @@ -371,10 +299,7 @@ static const unsigned char sha512_padding[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -/* - * SHA-512 final digest - */ -int mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char *output ) +static int esp_sha512_finish(esp_sha512_context *ctx, unsigned char *output) { int ret = -1; size_t last, padn; @@ -391,16 +316,15 @@ int mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char *output ) last = (size_t)( ctx->total[0] & 0x7F ); padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); - if ( ( ret = mbedtls_sha512_update( ctx, sha512_padding, padn ) ) != 0 ) { + if ( ( ret = esp_sha512_update( ctx, sha512_padding, padn ) ) != 0 ) { goto out; } - if ( ( ret = mbedtls_sha512_update( ctx, msglen, 16 ) ) != 0 ) { + if ( ( ret = esp_sha512_update( ctx, msglen, 16 ) ) != 0 ) { goto out; } - /* if state is in hardware, read it out */ - if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_read_digest_state(sha_type(ctx), ctx->state); } @@ -411,18 +335,128 @@ int mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char *output ) PUT_UINT64_BE( ctx->state[4], output, 32 ); PUT_UINT64_BE( ctx->state[5], output, 40 ); - if ( ctx->is384 == 0 ) { + if ( ctx->mode == SHA2_512 ) { PUT_UINT64_BE( ctx->state[6], output, 48 ); PUT_UINT64_BE( ctx->state[7], output, 56 ); } out: - if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) { + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { esp_sha_unlock_engine(sha_type(ctx)); - ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE; + ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; } return ret; } -#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */ +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) +{ + 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; +} + +psa_status_t esp_sha512_driver_abort(esp_sha512_context *ctx) +{ + if (!ctx) { + return PSA_ERROR_INVALID_ARGUMENT; + } + // Also unlock the hardware engine if it was in use + if (ctx->operation_mode == ESP_SHA_MODE_HARDWARE) { + esp_sha_unlock_engine(sha_type(ctx)); + ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; + } + memset(ctx, 0, sizeof(esp_sha512_context)); + return PSA_SUCCESS; +} + +psa_status_t esp_sha512_driver_clone(const esp_sha512_context *source_ctx, esp_sha512_context *target_ctx) +{ + if (source_ctx == NULL || target_ctx == NULL) { + return PSA_ERROR_INVALID_ARGUMENT; + } + memcpy(target_ctx, source_ctx, sizeof(esp_sha512_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_512, target_ctx->state); + target_ctx->operation_mode = ESP_SHA_MODE_SOFTWARE; // Cloned context operates in software mode + } + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c new file mode 100644 index 00000000000..c4296ea05a3 --- /dev/null +++ b/components/mbedtls/port/psa_driver/esp_sha/psa_crypto_driver_esp_sha.c @@ -0,0 +1,341 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "mbedtls/esp_config.h" +#include "psa_crypto_driver_esp_sha.h" +#include "include/psa_crypto_driver_esp_sha1.h" +#include "include/psa_crypto_driver_esp_sha256.h" +#include "include/psa_crypto_driver_esp_sha512.h" +#include "psa/crypto.h" +#include "psa/crypto_sizes.h" +#include "esp_log.h" +#include "esp_heap_caps.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 (!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 = heap_caps_malloc(sizeof(esp_sha1_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + if (!sha1_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memset(sha1_ctx, 0, sizeof(esp_sha1_context)); + operation->sha_ctx = sha1_ctx; + operation->sha_type = ESP_SHA_OPERATION_TYPE_SHA1; + return esp_sha1_starts(sha1_ctx); + } 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 = heap_caps_malloc(sizeof(esp_sha256_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + if (!sha256_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memset(sha256_ctx, 0, sizeof(esp_sha256_context)); + operation->sha_ctx = sha256_ctx; + int mode; +#if CONFIG_SOC_SHA_SUPPORT_SHA224 + operation->sha_type = (alg == PSA_ALG_SHA_224) ? ESP_SHA_OPERATION_TYPE_SHA224 : ESP_SHA_OPERATION_TYPE_SHA256; + mode = (alg == PSA_ALG_SHA_224) ? SHA2_224 : SHA2_256; +#else + operation->sha_type = ESP_SHA_OPERATION_TYPE_SHA256; + mode = SHA2_256; +#endif // CONFIG_SOC_SHA_SUPPORT_SHA224 + return esp_sha256_starts(sha256_ctx, mode); + } 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 = heap_caps_malloc(sizeof(esp_sha512_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + if (!sha512_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memset(sha512_ctx, 0, sizeof(esp_sha512_context)); + operation->sha_ctx = sha512_ctx; + int 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; + mode = (alg == PSA_ALG_SHA_384) ? SHA2_384 : SHA2_512; +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 + return esp_sha512_starts(sha512_ctx, mode); + } +#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 CONFIG_SOC_SHA_SUPPORT_SHA1 + if (operation->sha_type == ESP_SHA_OPERATION_TYPE_SHA1) { + esp_sha1_context *ctx = (esp_sha1_context *)operation->sha_ctx; + if (ctx) { + esp_sha1_driver_abort(ctx); + } + } 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; + if (ctx) { + esp_sha256_driver_abort(ctx); + } + } 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; + if (ctx) { + esp_sha512_driver_abort(ctx); + } + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 || CONFIG_SOC_SHA_SUPPORT_SHA512 + { + return PSA_ERROR_NOT_SUPPORTED; + } + 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) { + esp_sha1_context *sha1_ctx = heap_caps_malloc(sizeof(esp_sha1_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + if (!sha1_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memset(sha1_ctx, 0, sizeof(esp_sha1_context)); + target_operation->sha_ctx = sha1_ctx; + if (!target_operation->sha_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + esp_sha1_driver_clone(source_operation->sha_ctx, target_operation->sha_ctx); + } 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) { + esp_sha256_context *sha256_ctx = heap_caps_malloc(sizeof(esp_sha256_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + if (!sha256_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memset(sha256_ctx, 0, sizeof(esp_sha256_context)); + target_operation->sha_ctx = sha256_ctx; + if (!target_operation->sha_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + esp_sha256_driver_clone(source_operation->sha_ctx, target_operation->sha_ctx); + } 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) { + esp_sha512_context *sha512_ctx = heap_caps_malloc(sizeof(esp_sha512_context), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + if (!sha512_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + memset(sha512_ctx, 0, sizeof(esp_sha512_context)); + target_operation->sha_ctx = sha512_ctx; + if (!target_operation->sha_ctx) { + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + esp_sha512_driver_clone(source_operation->sha_ctx, target_operation->sha_ctx); + } else +#endif // CONFIG_SOC_SHA_SUPPORT_SHA384 || CONFIG_SOC_SHA_SUPPORT_SHA512 + { + return PSA_ERROR_NOT_SUPPORTED; + } + return PSA_SUCCESS; +} diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h new file mode 100644 index 00000000000..5d24896213e --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes.h @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ESP_AES_DRIVER_ENABLED) +#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#endif + +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_aes_contexts.h" + +psa_status_t esp_aes_cipher_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *iv, + size_t iv_length, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +psa_status_t esp_crypto_aes_encrypt_setup( + esp_aes_operation_t *esp_aes_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg); + +psa_status_t esp_crypto_aes_set_iv( + esp_aes_operation_t *esp_aes_driver_ctx, + const uint8_t *iv, size_t iv_length); + +psa_status_t esp_crypto_aes_update( + esp_aes_operation_t *esp_aes_driver_ctx, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, + size_t *output_length); + +psa_status_t esp_crypto_aes_finish( + esp_aes_operation_t *esp_aes_driver_ctx, + uint8_t *output, size_t output_size, + size_t *output_length); + +psa_status_t esp_crypto_aes_abort(esp_aes_operation_t *esp_aes_driver_ctx); + +psa_status_t esp_aes_cipher_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key, size_t key_length, + psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, size_t *output_length); + +psa_status_t esp_aes_cipher_decrypt_setup( + esp_aes_operation_t *esp_aes_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg); + +psa_status_t esp_aes_cipher_encrypt_setup( + esp_aes_operation_t *esp_aes_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg); + +psa_status_t esp_aes_cipher_set_iv( + esp_aes_operation_t *operation, + const uint8_t *iv, + size_t iv_length); + +psa_status_t esp_aes_cipher_update( + esp_aes_operation_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +psa_status_t esp_aes_cipher_finish( + esp_aes_operation_t *operation, + uint8_t *output, + size_t output_size, + size_t *output_length); + +psa_status_t esp_aes_cipher_abort( + esp_aes_operation_t *operation); +#endif /* ESP_AES_DRIVER_ENABLED */ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h new file mode 100644 index 00000000000..48475730ac8 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_contexts.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file psa_crypto_driver_esp_sha_contexts.h + * + * \brief Context structure definitions for ESP SHA hardware driver. + * + * This file contains the context structures used by the ESP SHA driver + * for PSA Crypto API. These definitions are completely standalone and + * do not include any PSA Crypto headers to avoid circular dependencies. + * + * \note This file may not be included directly. It is included by + * crypto_driver_contexts_primitives.h. + */ + +#include +#include + + +#if defined(ESP_AES_DRIVER_ENABLED) +#define ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH 16 +#define ESP_MBEDTLS_AES_MAX_IV_LENGTH 16 + +typedef struct { + void *esp_aes_ctx; + uint8_t iv[ESP_MBEDTLS_AES_MAX_IV_LENGTH]; + uint8_t unprocessed_data[ESP_MBEDTLS_AES_MAX_BLOCK_LENGTH]; + size_t unprocessed_len; + psa_algorithm_t aes_alg; + psa_encrypt_or_decrypt_t mode; + uint8_t block_length; +} esp_aes_operation_t; + +typedef struct { + void *esp_aes_gcm_ctx; + psa_encrypt_or_decrypt_t mode; +} esp_aes_gcm_operation_t; + +#endif /* ESP_AES_DRIVER_ENABLED */ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_gcm.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_gcm.h new file mode 100644 index 00000000000..baf4504bc36 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_aes_gcm.h @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +// #include_next "mbedtls/gcm.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined(ESP_AES_DRIVER_ENABLED) || defined(MBEDTLS_HARDWARE_GCM)) +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_aes_contexts.h" + +psa_status_t esp_crypto_aes_gcm_encrypt_setup( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg); + +psa_status_t esp_crypto_aes_gcm_decrypt_setup( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg); + +psa_status_t esp_crypto_aes_gcm_set_nonce( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const uint8_t *nonce, + size_t nonce_length); + +psa_status_t esp_crypto_aes_gcm_update_ad( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const uint8_t *aad, + size_t aad_length); + +psa_status_t esp_crypto_aes_gcm_update( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +psa_status_t esp_crypto_aes_gcm_finish( + esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx, + uint8_t *output, + size_t output_size, + size_t *output_length, + uint8_t *tag, + size_t tag_size, + size_t *tag_length); + +psa_status_t esp_crypto_aes_gcm_abort(esp_aes_gcm_operation_t *esp_aes_gcm_driver_ctx); + +psa_status_t esp_crypto_aes_gcm_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length); + +psa_status_t esp_crypto_aes_gcm_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length); + +#endif /* ESP_AES_DRIVER_ENABLED */ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h new file mode 100644 index 00000000000..c50322a3898 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ESP_AES_DRIVER_ENABLED) + +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_cmac_contexts.h" + + +psa_status_t esp_cmac_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length); + +psa_status_t esp_cmac_mac_abort(esp_cmac_operation_t *operation); + +psa_status_t esp_cmac_mac_setup(esp_cmac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg); + +psa_status_t esp_cmac_mac_update(esp_cmac_operation_t *cmac, + const uint8_t *data, + size_t data_length); + +psa_status_t esp_cmac_mac_finish( + esp_cmac_operation_t *hmac, + uint8_t *mac, + size_t mac_size, + size_t *mac_length); + +psa_status_t esp_cmac_mac_verify_finish( + esp_cmac_operation_t *operation, + const uint8_t *mac, + size_t mac_length); +#endif /* ESP_AES_DRIVER_ENABLED */ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h new file mode 100644 index 00000000000..d3427c64d00 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_cmac_contexts.h @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ESP_AES_DRIVER_ENABLED) || defined(PSA_CRYPTO_DRIVER_TEST) + +#if defined(ESP_SHA_DRIVER_ENABLED) +#include "psa_crypto_driver_esp_sha_contexts.h" +#include "psa_crypto_driver_esp_sha.h" +#endif /* ESP_SHA_DRIVER_ENABLED */ + +#define PSA_AES_BLOCK_SIZE PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES) +#define PSA_DES_BLOCK_SIZE PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_DES) + +#if defined(PSA_WANT_KEY_TYPE_AES) +#define PSA_CMAC_MAX_BLOCK_SIZE PSA_AES_BLOCK_SIZE /**< The longest block used by CMAC is that of AES. */ +#else +#define PSA_CMAC_MAX_BLOCK_SIZE PSA_DES_BLOCK_SIZE /**< The longest block used by CMAC is that of 3DES. */ +#endif + +typedef struct { + /** The CMAC key identifier for cipher operations */ + psa_key_id_t key_id; + + /** The internal state of the CMAC algorithm. */ + unsigned char state[PSA_CMAC_MAX_BLOCK_SIZE]; + + /** Unprocessed data - either data that was not block aligned and is still + * pending processing, or the final block. */ + unsigned char unprocessed_block[PSA_CMAC_MAX_BLOCK_SIZE]; + + /** The length of data pending processing. */ + size_t unprocessed_len; + + uint8_t cipher_block_length; + + struct psa_cipher_operation_s cipher_ctx; + + psa_algorithm_t alg; +#if defined(ESP_SHA_DRIVER_ENABLED) + esp_sha_hash_operation_t hmac_operation; + uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; +#endif /* ESP_SHA_DRIVER_ENABLED */ +} esp_cmac_operation_t; + +#endif /* ESP_AES_DRIVER_ENABLED */ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h new file mode 100644 index 00000000000..2c686a45548 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha.h @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "psa_crypto_driver_esp_sha_contexts.h" +#include +#include "psa/crypto.h" + +#ifdef CONFIG_MBEDTLS_HARDWARE_SHA +#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT +#endif +#endif // CONFIG_MBEDTLS_HARDWARE_SHA + +#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); + +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); +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h new file mode 100644 index 00000000000..658a1279f03 --- /dev/null +++ b/components/mbedtls/port/psa_driver/include/psa_crypto_driver_esp_sha_contexts.h @@ -0,0 +1,124 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file psa_crypto_driver_esp_sha_contexts.h + * + * \brief Context structure definitions for ESP SHA hardware driver. + * + * This file contains the context structures used by the ESP SHA driver + * for PSA Crypto API. These definitions are completely standalone and + * do not include any PSA Crypto headers to avoid circular dependencies. + * + * \note This file may not be included directly. It is included by + * crypto_driver_contexts_primitives.h. + */ + +#include +#include +#include "sdkconfig.h" + +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; + +#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG +typedef enum { + ESP_SHA_MODE_UNUSED, + ESP_SHA_MODE_HARDWARE, + ESP_SHA_MODE_SOFTWARE +} esp_sha_mode_t; +#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */ + +/** + * \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 */ +#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG + esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */ +#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */ +} 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 */ +#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG + esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */ +#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */ +} 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 */ +#if CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG + esp_sha_mode_t operation_mode; /*!< Hardware or Software mode */ +#endif /* CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG */ +} 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; + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/sha/core/esp_sha1.c b/components/mbedtls/port/sha/core/esp_sha1.c deleted file mode 100644 index 1359dc94b97..00000000000 --- a/components/mbedtls/port/sha/core/esp_sha1.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * SHA-1 implementation with hardware ESP support added. - * - * SPDX-FileCopyrightText: The Mbed TLS Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2016-2025 Espressif Systems (Shanghai) CO LTD - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#include - -#if defined(MBEDTLS_SHA1_ALT) - -#include "mbedtls/sha1.h" - -#include -#include -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#include "esp_sha_internal.h" -#include "sha/sha_core.h" -#include "esp_compiler.h" - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize(void *v, size_t n) -{ - volatile unsigned char *p = (unsigned char *)v; - while (n--) { - *p++ = 0; - } -} - -/* - * 32-bit integer manipulation macros (big endian) - */ - -#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 - -void mbedtls_sha1_init(mbedtls_sha1_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_sha1_context)); -} - -void mbedtls_sha1_free(mbedtls_sha1_context *ctx) -{ - if (ctx == NULL) { - return; - } - mbedtls_zeroize(ctx, sizeof(mbedtls_sha1_context)); -} - -void mbedtls_sha1_clone(mbedtls_sha1_context *dst, - const mbedtls_sha1_context *src) -{ - memcpy(dst, src, sizeof(mbedtls_sha1_context)); -} - -/* - * SHA-1 context setup - */ -int mbedtls_sha1_starts(mbedtls_sha1_context *ctx) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - memset(ctx, 0, sizeof(mbedtls_sha1_context)); - ctx->mode = SHA1; - - return 0; -} - -static void esp_internal_sha_update_state(mbedtls_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(ctx->mode, ctx->state); - } -} - -static void esp_internal_sha1_block_process(mbedtls_sha1_context *ctx, const uint8_t *data) -{ - esp_sha_block(SHA1, data, ctx->first_block); - - if (ctx->first_block) { - ctx->first_block = false; - } -} - -int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64]) -{ - esp_sha_acquire_hardware(); - - esp_sha_set_mode(ctx->mode); - - 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(ctx->mode, data, ctx->first_block); - } - - esp_sha_read_digest_state(ctx->mode, ctx->state); - esp_sha_release_hardware(); - return 0; -} - -int mbedtls_sha1_update(mbedtls_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(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(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 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 -}; - -/* -* SHA-1 final digest - */ -int mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20]) -{ - 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 = mbedtls_sha1_update(ctx, sha1_padding, padn)) != 0) { - return ret; - } - if ((ret = mbedtls_sha1_update(ctx, msglen, 8)) != 0) { - return ret; - } - - memcpy(output, ctx->state, 20); - - return ret; -} - -#endif /* MBEDTLS_SHA1_ALT */ diff --git a/components/mbedtls/port/sha/core/esp_sha256.c b/components/mbedtls/port/sha/core/esp_sha256.c deleted file mode 100644 index dad3c571e84..00000000000 --- a/components/mbedtls/port/sha/core/esp_sha256.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * SHA-256 implementation with hardware ESP support added. - * - * SPDX-FileCopyrightText: The Mbed TLS Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2016-2025 Espressif Systems (Shanghai) CO LTD - */ -/* - * The SHA-256 Secure Hash Standard was published by NIST in 2002. - * - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - */ - -#include - -#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT) - -#include "mbedtls/sha256.h" - -#include -#include -#include - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#include "esp_sha_internal.h" -#include "sha/sha_core.h" -#include "esp_compiler.h" - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize(void *v, size_t n) -{ - volatile unsigned char *p = v; - while (n--) { - *p++ = 0; - } -} - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -do { \ - (n) = ((uint32_t) (b)[(i) ] << 24) \ - | ((uint32_t) (b)[(i) + 1] << 16) \ - | ((uint32_t) (b)[(i) + 2] << 8) \ - | ((uint32_t) (b)[(i) + 3] ); \ -} while(0) -#endif - -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -do { \ - (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) ); \ -} while(0) -#endif - -void mbedtls_sha256_init(mbedtls_sha256_context *ctx) -{ - memset(ctx, 0, sizeof(mbedtls_sha256_context)); -} - -void mbedtls_sha256_free(mbedtls_sha256_context *ctx) -{ - if (ctx == NULL) { - return; - } - - mbedtls_zeroize(ctx, sizeof(mbedtls_sha256_context)); -} - -void mbedtls_sha256_clone(mbedtls_sha256_context *dst, - const mbedtls_sha256_context *src) -{ - *dst = *src; -} - -/* - * SHA-256 context setup - */ -int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224) -{ - memset(ctx, 0, sizeof(mbedtls_sha256_context)); - - if (is224) { - ctx->mode = SHA2_224; - } else { - ctx->mode = SHA2_256; - } - - return 0; -} - -static void esp_internal_sha_update_state(mbedtls_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 void esp_internal_sha256_block_process(mbedtls_sha256_context *ctx, const uint8_t *data) -{ - esp_sha_block(ctx->mode, data, ctx->first_block); - - if (ctx->first_block) { - ctx->first_block = false; - } -} - -int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64]) -{ - esp_sha_acquire_hardware(); - - esp_sha_set_mode(ctx->mode); - - 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(ctx->mode, 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(ctx->mode, data, ctx->first_block); - } - - esp_sha_read_digest_state(ctx->mode, ctx->state); - esp_sha_release_hardware(); - return 0; -} - -/* - * SHA-256 process buffer - */ -int mbedtls_sha256_update(mbedtls_sha256_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 = 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 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 -}; - -/* - * SHA-256 final digest - */ -int mbedtls_sha256_finish(mbedtls_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 = mbedtls_sha256_update(ctx, sha256_padding, padn)) != 0) { - return ret; - } - - if ((ret = mbedtls_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 ret; -} - -#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */ diff --git a/components/mbedtls/port/sha/esp_sha.c b/components/mbedtls/port/sha/esp_sha.c index cd897975b47..0c39bf6e74d 100644 --- a/components/mbedtls/port/sha/esp_sha.c +++ b/components/mbedtls/port/sha/esp_sha.c @@ -7,15 +7,15 @@ #include #include #include + +#include "psa/crypto.h" + #include "hal/sha_hal.h" #include "hal/sha_types.h" +#include "psa/crypto_sizes.h" #include "soc/soc_caps.h" #include "esp_log.h" -#include -#include -#include - #if SOC_SHA_SUPPORT_PARALLEL_ENG #include "sha/sha_parallel_engine.h" #else @@ -26,88 +26,57 @@ static const char *TAG = "esp_sha"; void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output) { - union { -#if SOC_SHA_SUPPORT_SHA1 - mbedtls_sha1_context sha1; -#endif -#if SOC_SHA_SUPPORT_SHA224 || SOC_SHA_SUPPORT_SHA256 - mbedtls_sha256_context sha256; -#endif -#if SOC_SHA_SUPPORT_SHA384 || SOC_SHA_SUPPORT_SHA512 - mbedtls_sha512_context sha512; -#endif - } ctx; - int ret __attribute__((unused)); assert(input != NULL && output != NULL); + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_NONE; + #if SOC_SHA_SUPPORT_SHA1 if (sha_type == SHA1) { - mbedtls_sha1_init(&ctx.sha1); - mbedtls_sha1_starts(&ctx.sha1); - ret = mbedtls_sha1_update(&ctx.sha1, input, ilen); - assert(ret == 0); - ret = mbedtls_sha1_finish(&ctx.sha1, output); - assert(ret == 0); - mbedtls_sha1_free(&ctx.sha1); - return; + alg = PSA_ALG_SHA_1; } #endif //SOC_SHA_SUPPORT_SHA1 #if SOC_SHA_SUPPORT_SHA224 if (sha_type == SHA2_224) { - mbedtls_sha256_init(&ctx.sha256); - mbedtls_sha256_starts(&ctx.sha256, 1); - ret = mbedtls_sha256_update(&ctx.sha256, input, ilen); - assert(ret == 0); - ret = mbedtls_sha256_finish(&ctx.sha256, output); - assert(ret == 0); - mbedtls_sha256_free(&ctx.sha256); - return; + alg = PSA_ALG_SHA_224; } #endif //SOC_SHA_SUPPORT_SHA224 #if SOC_SHA_SUPPORT_SHA256 if (sha_type == SHA2_256) { - mbedtls_sha256_init(&ctx.sha256); - mbedtls_sha256_starts(&ctx.sha256, 0); - ret = mbedtls_sha256_update(&ctx.sha256, input, ilen); - assert(ret == 0); - ret = mbedtls_sha256_finish(&ctx.sha256, output); - assert(ret == 0); - mbedtls_sha256_free(&ctx.sha256); - return; + alg = PSA_ALG_SHA_256; } #endif //SOC_SHA_SUPPORT_SHA256 #if SOC_SHA_SUPPORT_SHA384 if (sha_type == SHA2_384) { - mbedtls_sha512_init(&ctx.sha512); - mbedtls_sha512_starts(&ctx.sha512, 1); - ret = mbedtls_sha512_update(&ctx.sha512, input, ilen); - assert(ret == 0); - ret = mbedtls_sha512_finish(&ctx.sha512, output); - assert(ret == 0); - mbedtls_sha512_free(&ctx.sha512); - return; + alg = PSA_ALG_SHA_384; } #endif //SOC_SHA_SUPPORT_SHA384 #if SOC_SHA_SUPPORT_SHA512 if (sha_type == SHA2_512) { - mbedtls_sha512_init(&ctx.sha512); - mbedtls_sha512_starts(&ctx.sha512, 0); - ret = mbedtls_sha512_update(&ctx.sha512, input, ilen); - assert(ret == 0); - ret = mbedtls_sha512_finish(&ctx.sha512, output); - assert(ret == 0); - mbedtls_sha512_free(&ctx.sha512); - return; + alg = PSA_ALG_SHA_512; } #endif //SOC_SHA_SUPPORT_SHA512 - ESP_LOGE(TAG, "SHA type %d not supported", (int)sha_type); - abort(); + if (alg == PSA_ALG_NONE) { + ESP_LOGE(TAG, "SHA type %d not supported", (int)sha_type); + abort(); + } + size_t olen; + size_t output_len = PSA_HASH_LENGTH(alg); + status = psa_hash_compute(alg, input, ilen, output, output_len, &olen); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "SHA computation failed, status %d", status); + abort(); + } + if (olen != output_len) { + ESP_LOGE(TAG, "SHA output length mismatch, expected %u, got %u", output_len, olen); + abort(); + } } diff --git a/components/mbedtls/test_apps/main/CMakeLists.txt b/components/mbedtls/test_apps/main/CMakeLists.txt index c70fe8198de..842f1ce872d 100644 --- a/components/mbedtls/test_apps/main/CMakeLists.txt +++ b/components/mbedtls/test_apps/main/CMakeLists.txt @@ -3,8 +3,13 @@ set(TEST_CRTS "crts/server_cert_chain.pem" "crts/server_cert_bundle" "crts/bad_md_crt.pem" "crts/wrong_sig_crt_esp32_com.pem" - "crts/correct_sig_crt_esp32_com.pem") -idf_component_register(SRC_DIRS "." + "crts/correct_sig_crt_esp32_com.pem" + "crts/ecdsa_cert_bundle" + "crts/ecdsa_correct_sig_crt.pem" + "crts/ecdsa_wrong_sig_crt.pem") + +idf_component_register( + SRC_DIRS "." PRIV_INCLUDE_DIRS "." PRIV_REQUIRES efuse cmock test_utils mbedtls esp_timer unity spi_flash esp_psram esp_security EMBED_TXTFILES ${TEST_CRTS} @@ -13,7 +18,6 @@ idf_component_register(SRC_DIRS "." idf_component_get_property(mbedtls mbedtls COMPONENT_LIB) target_compile_definitions(${mbedtls} INTERFACE "-DMBEDTLS_DEPRECATED_WARNING") target_compile_definitions(mbedtls PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") -target_compile_definitions(mbedcrypto PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") target_compile_definitions(mbedx509 PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") # Add linker wrap option to override esp_ds_finish_sign diff --git a/components/mbedtls/test_apps/main/app_main.c b/components/mbedtls/test_apps/main/app_main.c index 20792fb592e..dc1ad018258 100644 --- a/components/mbedtls/test_apps/main/app_main.c +++ b/components/mbedtls/test_apps/main/app_main.c @@ -1,15 +1,19 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ +#include +#include "psa/crypto.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unity.h" -#include "mbedtls/aes.h" #include "memory_checks.h" #include "soc/soc_caps.h" #include "esp_newlib.h" +#include "esp_random.h" + +#define CALL_SZ (32 * 1024) /* setUp runs before every test */ void setUp(void) @@ -17,8 +21,25 @@ void setUp(void) // Execute mbedtls_aes_init operation to allocate AES interrupt // allocation memory which is considered as leak otherwise #if SOC_AES_SUPPORTED - mbedtls_aes_context ctx; - mbedtls_aes_init(&ctx); + uint8_t iv[16]; + uint8_t key[16]; + memset(iv, 0xEE, 16); + memset(key, 0x44, 16); + + uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(buf); + psa_key_id_t key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_import_key(&attributes, key, sizeof(key), &key_id); + + size_t output_length = 0; + psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, buf, CALL_SZ, buf, CALL_SZ, &output_length); + heap_caps_free(buf); + psa_destroy_key(key_id); #endif // SOC_AES_SUPPORTED test_utils_record_free_mem(); diff --git a/components/mbedtls/test_apps/main/crts/ecdsa_cert_bundle b/components/mbedtls/test_apps/main/crts/ecdsa_cert_bundle new file mode 100644 index 00000000000..edf295072f6 Binary files /dev/null and b/components/mbedtls/test_apps/main/crts/ecdsa_cert_bundle differ diff --git a/components/mbedtls/test_apps/main/crts/ecdsa_correct_sig_crt.pem b/components/mbedtls/test_apps/main/crts/ecdsa_correct_sig_crt.pem new file mode 100644 index 00000000000..591464c571e --- /dev/null +++ b/components/mbedtls/test_apps/main/crts/ecdsa_correct_sig_crt.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIUTbvKUa+55zFxQhgDIQ91RdGXEXIwCgYIKoZIzj0EAwQw +YDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3QxFjAU +BgNVBAoMDVRlc3QgRUNEU0EgQ0ExGzAZBgNVBAMMElRlc3QgRUNEU0EgUm9vdCBD +QTAeFw0yNTExMDMwODAzNTdaFw0yNjExMDMwODAzNTdaMGIxCzAJBgNVBAYTAlVT +MQ0wCwYDVQQIDARUZXN0MQ0wCwYDVQQHDARUZXN0MRQwEgYDVQQKDAtUZXN0IFNl +cnZlcjEfMB0GA1UEAwwWZWNkc2EtdGVzdC5leGFtcGxlLmNvbTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABFd+Bd6HtASMpEytx+QfDk8I0DX73EKQ3tR2TUJuhg7B2epc +qqmMXZ5KQpOY/+V0kv1WyLCDisw7vP6d4yQjokSJqEnaO3af5TJh0WCjWJsVtNZy +VAQMS9lxSZW1a1lle6NCMEAwHQYDVR0OBBYEFNJ2LzJjqMZXRjY0NNvVTS3Crsjh +MB8GA1UdIwQYMBaAFElMhoUHf0Loi7Kzcpp0t4AfUBsuMAoGCCqGSM49BAMEA2cA +MGQCMCiXh9m1BOkedod4lVzKLx535sLbFM7OxnYFxYOCK4Q3djtgxjy0OFmlyD5I +YLUfxAIwO35NHh06OMyOI85NJbOYD2oPDiju/1JYHhER9rPAFrJJtwKGhNlMufqk +V+9SwUK2 +-----END CERTIFICATE----- diff --git a/components/mbedtls/test_apps/main/crts/ecdsa_wrong_sig_crt.pem b/components/mbedtls/test_apps/main/crts/ecdsa_wrong_sig_crt.pem new file mode 100644 index 00000000000..04854574921 --- /dev/null +++ b/components/mbedtls/test_apps/main/crts/ecdsa_wrong_sig_crt.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIUTbvKUa+55zFxQhgDIQ91RdGXEXIwCgYIKoZIzj0EAwQw +YDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3QxFjAU +BgNVBAoMDVRlc3QgRUNEU0EgQ0ExGzAZBgNVBAMMElRlc3QgRUNEU0EgUm9vdCBD +QTAeFw0yNTExMDMwODAzNTdaFw0yNjExMDMwODAzNTdaMGIxCzAJBgNVBAYTAlVT +MQ0wCwYDVQQIDARUZXN0MQ0wCwYDVQQHDARUZXN0MRQwEgYDVQQKDAtUZXN0IFNl +cnZlcjEfMB0GA1UEAwwWZWNkc2EtdGVzdC5leGFtcGxlLmNvbTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABFd+Bd6HtASMpEytx+QfDk8I0DX73EKQ3tR2TUJuhg7B2epc +qqmMXZ5KQpOY/+V0kv1WyLCDisw7vP6d4yQjokSJqEnaO3af5TJh0WCjWJsVtNZy +VAQMS9lxSZW1a1lle6NCMEAwHQYDVR0OBBYEFNJ2LzJjqMZXRjY0NNvVTS3Crsjh +MB8GA1UdIwQYMBaAFElMhoUHf0Loi7Kzcpp0t4AfUBsuMAoGCCqGSM49BAMEA2cA +MGQCMCiXh9m1BOkedod4lVzKMx535sLbFM7OxnYFxYOCK4Q3djtgxjy0OFmlyD5I +YLUfxAIwO35NHh06OMyOI85NJbOYD2oPDiju/1JYHhER9rPAFrJJtwKGhNlMufqk +V+9SwUK2 +-----END CERTIFICATE----- diff --git a/components/mbedtls/test_apps/main/test_aes.c b/components/mbedtls/test_apps/main/test_aes.c deleted file mode 100644 index 347b7111f11..00000000000 --- a/components/mbedtls/test_apps/main/test_aes.c +++ /dev/null @@ -1,2079 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -/* mbedTLS AES test -*/ -#include -#include -#include -#include -#include "mbedtls/aes.h" -#include "mbedtls/gcm.h" -#include "unity.h" -#include "sdkconfig.h" -#include "esp_log.h" -#include "esp_timer.h" -#include "esp_heap_caps.h" -#include "test_utils.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "esp_memory_utils.h" -#include "soc/lldesc.h" - -#define INTERNAL_DMA_CAPS (MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL) -#define PSRAM_DMA_CAPS (MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM) - -#define TEST_AES_CBC_DMA_MODE_LEN 1600 -#define TEST_AES_CTR_DMA_MODE_LEN 1000 -#define TEST_AES_OFB_DMA_MODE_LEN 1000 -#define TEST_AES_CFB8_DMA_MODE_LEN 1000 -#define TEST_AES_CFB128_DMA_MODE_LEN 1000 -#define TEST_AES_CTR_STREAM_DMA_MODE_LEN 1000 -#define TEST_AES_OFB_STREAM_DMA_MODE_LEN 1000 -#define TEST_AES_CFB8_STREAM_DMA_MODE_LEN 1000 -#define TEST_AES_CFB128_STREAM_DMA_MODE_LEN 1000 - -static const uint8_t key_256[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, -}; - -static const uint8_t iv[] = { - 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, - 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, -}; - -/* Cipher produced via this Python: - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - from cryptography.hazmat.backends import default_backend - - def as_c_array(byte_arr): - - hex_str = '' - for idx, byte in enumerate(byte_arr): - hex_str += "0x{:02x}, ".format(byte) - bytes_per_line = 8 - if idx % bytes_per_line == bytes_per_line - 1: - hex_str += '\n' - - return hex_str - - key = bytearray(range(32)) - iv = bytearray(range(16, 0, -1)) - - print("Key: \n{}".format(as_c_array(key))) - print("IV: \n{}".format(as_c_array(iv))) - - # Replace CTR with desired mode - cipher = Cipher(algorithms.AES(key), modes.CTR(iv), backend=default_backend()) - encryptor = cipher.encryptor() - - input_len = 1000 - - plain = b'\x3A'*input_len - print(as_c_array(plain)) - ct = encryptor.update(plain) + encryptor.finalize() - - print("Ciphertext: {}".format(as_c_array(ct))) -*/ - -static void aes_cbc_test(unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - - const uint8_t expected_cipher_end[] = { - 0x3e, 0x68, 0x8a, 0x02, 0xe6, 0xf2, 0x6a, 0x9e, - 0x9b, 0xb2, 0xc0, 0xc4, 0x63, 0x63, 0xd9, 0x25, - 0x51, 0xdc, 0xc2, 0x71, 0x96, 0xb3, 0xe5, 0xcd, - 0xbd, 0x0e, 0xf2, 0xef, 0xa9, 0xab, 0xab, 0x2d, - }; - - memcpy(nonce, iv, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); - - memset(plaintext, 0x3A, SZ); - memset(decryptedtext, 0x0, SZ); - - // Encrypt - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, SZ, nonce, plaintext, ciphertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32); - - // Decrypt - memcpy(nonce, iv, 16); - mbedtls_aes_setkey_dec(&ctx, key_256, 256); - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, SZ, nonce, ciphertext, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls CBC AES-256 test", "[aes]") -{ - aes_cbc_test(TEST_AES_CBC_DMA_MODE_LEN); -} - -TEST_CASE("mbedtls CBC AES-256 DMA buffer align test", "[aes]") -{ -#define ALIGN_DOWN(val, align) ((val) & ~((align) - 1)) - // Size is taken considering the maximum DMA buffer size - const unsigned SZ = ALIGN_DOWN((2*LLDESC_MAX_NUM_PER_DESC), 16); - mbedtls_aes_context ctx; - uint8_t nonce[16]; - - const uint8_t expected_cipher_end[] = { - 0x9e, 0xcb, 0x1d, 0x24, 0x01, 0xc8, 0x3f, 0xba, - 0xde, 0x76, 0xea, 0x9c, 0xf3, 0x64, 0x23, 0x19, - 0x8c, 0x67, 0xd4, 0x1a, 0xd1, 0xe0, 0xbf, 0xc3, - 0xd2, 0xb8, 0x40, 0x95, 0x89, 0x41, 0x09, 0xdb, - }; - - memcpy(nonce, iv, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); - - memset(plaintext, 0x3A, SZ); - memset(decryptedtext, 0x0, SZ); - - // Encrypt - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, SZ, nonce, plaintext, ciphertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32); - - // Decrypt - memcpy(nonce, iv, 16); - mbedtls_aes_setkey_dec(&ctx, key_256, 256); - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, SZ, nonce, ciphertext, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -static void aes_ctr_test(unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - uint8_t stream_block[16]; - size_t nc_off = 0; - - const uint8_t expected_cipher_end[] = { - 0xd4, 0xdc, 0x4f, 0x8f, 0xfe, 0x86, 0xee, 0xb5, - 0x14, 0x7f, 0xba, 0x30, 0x25, 0xa6, 0x7f, 0x6c, - 0xb5, 0x73, 0xaf, 0x90, 0xd7, 0xff, 0x36, 0xba, - 0x2b, 0x1d, 0xec, 0xb9, 0x38, 0xfa, 0x0d, 0xeb, - }; - - memcpy(nonce, iv, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); - - memset(plaintext, 0x3A, SZ); - memset(decryptedtext, 0x0, SZ); - - // Encrypt - mbedtls_aes_crypt_ctr(&ctx, SZ, &nc_off, nonce, stream_block, plaintext, ciphertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32); - - // Decrypt - nc_off = 0; - memcpy(nonce, iv, 16); - mbedtls_aes_crypt_ctr(&ctx, SZ, &nc_off, nonce, stream_block, ciphertext, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls CTR AES-256 test", "[aes]") -{ - aes_ctr_test(TEST_AES_CTR_DMA_MODE_LEN); -} - -static void aes_ofb_test(unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - size_t nc_off = 0; - - const uint8_t expected_cipher_end[] = { - 0xca, 0xc3, 0x05, 0x77, 0xae, 0xb9, 0x38, 0xd6, - 0x03, 0x0a, 0xad, 0x90, 0x6e, 0xdd, 0xf3, 0x9a, - 0x41, 0x4d, 0x71, 0x30, 0x04, 0x9f, 0xd3, 0x53, - 0xb7, 0x5e, 0xb4, 0xfd, 0x93, 0xf8, 0x31, 0x6a, - }; - - memcpy(nonce, iv, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); - - memset(plaintext, 0x3A, SZ); - memset(decryptedtext, 0x0, SZ); - - // Encrypt - mbedtls_aes_crypt_ofb(&ctx, SZ, &nc_off, nonce, plaintext, ciphertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32); - - // Decrypt - nc_off = 0; - memcpy(nonce, iv, 16); - mbedtls_aes_crypt_ofb(&ctx, SZ, &nc_off, nonce, ciphertext, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls OFB AES-256 test", "[aes]") -{ - aes_ofb_test(TEST_AES_OFB_DMA_MODE_LEN); -} - -static void aes_cfb8_test(unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - - const uint8_t expected_cipher_end[] = { - 0x69, 0xdc, 0x1d, 0x8a, 0x0b, 0x9e, 0xbc, 0x84, - 0x29, 0xa2, 0x04, 0xb6, 0x91, 0x6b, 0xb2, 0x83, - 0x13, 0x23, 0x54, 0xcb, 0xf9, 0x6d, 0xcc, 0x53, - 0x04, 0x59, 0xd1, 0xc9, 0xff, 0xab, 0xe2, 0x37, - }; - - memcpy(nonce, iv, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); - - memset(plaintext, 0x3A, SZ); - memset(decryptedtext, 0x0, SZ); - - // Encrypt - mbedtls_aes_crypt_cfb8(&ctx, MBEDTLS_AES_ENCRYPT, SZ, nonce, plaintext, ciphertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32); - - // Decrypt - memcpy(nonce, iv, 16); - mbedtls_aes_crypt_cfb8(&ctx, MBEDTLS_AES_DECRYPT, SZ, nonce, ciphertext, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls CFB-8 AES-256 test", "[aes]") -{ - aes_cfb8_test(TEST_AES_CFB8_DMA_MODE_LEN); -} - -static void aes_cfb128_test(unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - size_t nc_off = 0; - - const uint8_t expected_cipher_end[] = { - 0xf3, 0x64, 0x20, 0xa1, 0x70, 0x2a, 0xd9, 0x3f, - 0xb7, 0x48, 0x8c, 0x2c, 0x1f, 0x65, 0x53, 0xc2, - 0xac, 0xfd, 0x82, 0xe5, 0x31, 0x24, 0x1f, 0x30, - 0xaf, 0xcc, 0x8d, 0xb3, 0xf3, 0x63, 0xe1, 0xa0, - }; - - memcpy(nonce, iv, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); - - memset(plaintext, 0x3A, SZ); - memset(decryptedtext, 0x0, SZ); - - // Encrypt - mbedtls_aes_crypt_cfb128(&ctx, MBEDTLS_AES_ENCRYPT, SZ, &nc_off, nonce, plaintext, ciphertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32); - - // Decrypt - nc_off = 0; - memcpy(nonce, iv, 16); - mbedtls_aes_crypt_cfb128(&ctx, MBEDTLS_AES_DECRYPT, SZ, &nc_off, nonce, ciphertext, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls CFB-128 AES-256 test", "[aes]") -{ - aes_cfb128_test(TEST_AES_CFB128_DMA_MODE_LEN); -} - -static void aes_ctr_stream_test(uint32_t input_buf_caps, uint32_t output_buf_caps, unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - uint8_t key[16]; - uint8_t stream_block[16]; - - /* Cipher produced via this Python: - import os, binascii - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - from cryptography.hazmat.backends import default_backend - key = b'\x44' * 16 - nonce = b'\xee' * 16 - cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()) - encryptor = cipher.encryptor() - ct = encryptor.update(b'\xaa' * 1000) + encryptor.finalize() - ct_arr = "" - for idx, b in enumerate(ct): - if idx % 8 == 0: - ct_arr += '\n' - ct_arr += "0x{}, ".format(format(b, '02x')) - print(ct_arr) - */ - const uint8_t expected_cipher[] = { - 0xc5, 0x78, 0xa7, 0xb4, 0xf3, 0xb9, 0xcb, 0x8b, - 0x09, 0xe0, 0xd6, 0x89, 0x14, 0x6a, 0x19, 0x09, - 0xde, 0xaf, 0x37, 0x19, 0x32, 0x4d, 0xca, 0xf6, - 0xff, 0x6e, 0xd2, 0x5d, 0x87, 0x51, 0xaa, 0x8c, - 0x1c, 0xe3, 0x3b, 0xbb, 0x18, 0xf5, 0xa0, 0x1b, - 0xdc, 0x29, 0x52, 0x63, 0xf6, 0x5d, 0x49, 0x85, - 0x29, 0xf1, 0xf0, 0x69, 0x8f, 0xa6, 0x9f, 0x38, - 0x5c, 0xdd, 0x26, 0xf8, 0x9d, 0x40, 0xa1, 0xff, - 0x52, 0x46, 0xe1, 0x72, 0x70, 0x39, 0x73, 0xff, - 0xd0, 0x5e, 0xe5, 0x3f, 0xc5, 0xed, 0x5c, 0x18, - 0xa7, 0x84, 0xd8, 0xdf, 0x9d, 0xb5, 0x06, 0xb1, - 0xa7, 0xcf, 0x2e, 0x7a, 0x51, 0xfc, 0x44, 0xc5, - 0xb9, 0x5f, 0x22, 0x47, 0x91, 0xbd, 0x67, 0x89, - 0x15, 0xcd, 0x6a, 0xac, 0xa7, 0x8f, 0x6c, 0xff, - 0x64, 0xc4, 0xbd, 0x53, 0xb6, 0x24, 0x13, 0xd4, - 0x30, 0x3e, 0x80, 0xb9, 0x5f, 0xf6, 0x79, 0x4c, - 0x3c, 0x11, 0xce, 0x45, 0xb2, 0x4b, 0x70, 0x2d, - 0x73, 0xc8, 0x0d, 0x4c, 0x82, 0xa6, 0x8a, 0xe2, - 0x4e, 0x56, 0x07, 0xdf, 0xaf, 0x2a, 0x15, 0x08, - 0xef, 0x5d, 0x96, 0x69, 0xe9, 0xe7, 0xc0, 0x1f, - 0x7b, 0x67, 0x68, 0xaf, 0xe9, 0x9c, 0xb4, 0x15, - 0x49, 0x95, 0x1a, 0x71, 0xb3, 0x7b, 0x4b, 0x26, - 0xf1, 0x9e, 0x72, 0xf3, 0xa5, 0x24, 0x46, 0x96, - 0xda, 0x11, 0xd5, 0xa7, 0x05, 0xc4, 0x36, 0x11, - 0xb2, 0x01, 0x5d, 0xe8, 0x67, 0xe6, 0x4a, 0xe7, - 0x44, 0x22, 0xb9, 0xa8, 0x8f, 0x26, 0x62, 0x80, - 0x3e, 0xf5, 0xfe, 0x51, 0x46, 0x20, 0x23, 0x1b, - 0x97, 0xb4, 0x6e, 0x5c, 0xe9, 0x3e, 0xe3, 0x79, - 0xf4, 0xd0, 0xc6, 0x81, 0x59, 0x8d, 0x99, 0x55, - 0x12, 0x37, 0x55, 0x28, 0xda, 0x3d, 0x70, 0xc9, - 0x6a, 0xb9, 0xd7, 0xee, 0x55, 0x35, 0x0f, 0x96, - 0xde, 0x19, 0x6f, 0x44, 0xba, 0x66, 0x9b, 0xdd, - 0x5a, 0x7b, 0xc6, 0x45, 0xf8, 0x6e, 0x8b, 0xa1, - 0xf1, 0xe1, 0x44, 0x33, 0xe9, 0x10, 0x81, 0xed, - 0xba, 0x21, 0xf3, 0x01, 0xab, 0x78, 0x7d, 0x64, - 0x05, 0xda, 0xc7, 0xce, 0x34, 0x8d, 0x74, 0xef, - 0x22, 0xa8, 0x77, 0xc4, 0x43, 0x06, 0xcd, 0x29, - 0xfb, 0xc8, 0x20, 0x13, 0xbb, 0x41, 0xf2, 0x5c, - 0x3b, 0x99, 0x2e, 0xbe, 0xb0, 0xaa, 0x78, 0xd8, - 0xfa, 0xcd, 0x28, 0x30, 0x23, 0xc2, 0xd3, 0xb4, - 0x63, 0x0d, 0x46, 0x14, 0xa1, 0x73, 0xb7, 0xed, - 0xf8, 0xb8, 0x38, 0x0e, 0xde, 0x6a, 0x8a, 0x11, - 0x35, 0x7e, 0xe6, 0x55, 0x2d, 0xe8, 0xa1, 0xa1, - 0xa0, 0x79, 0x8a, 0x47, 0x50, 0xbe, 0x13, 0x93, - 0x05, 0x6c, 0x52, 0x7d, 0x41, 0x79, 0xcd, 0x64, - 0x45, 0x3e, 0xce, 0xa3, 0xa8, 0xf2, 0xa6, 0x0c, - 0xee, 0xf2, 0x13, 0xaa, 0x5d, 0xdc, 0x59, 0x5a, - 0x7a, 0x96, 0x1f, 0xe0, 0xcc, 0x10, 0x46, 0xcd, - 0xfa, 0x9d, 0x85, 0x25, 0xd0, 0x48, 0x2d, 0xb1, - 0x34, 0x81, 0xce, 0xd1, 0xae, 0x4d, 0xd8, 0x6f, - 0xea, 0xbe, 0x42, 0x68, 0x5a, 0xa5, 0x63, 0x68, - 0x86, 0x8a, 0x39, 0x78, 0x2f, 0x66, 0xd9, 0x85, - 0xbf, 0x88, 0x9a, 0x7e, 0xc7, 0xc2, 0x3a, 0xeb, - 0x5e, 0xc8, 0x3c, 0x35, 0xf2, 0xfc, 0x68, 0x21, - 0xca, 0x75, 0xbb, 0x3d, 0x53, 0x02, 0xe8, 0xb1, - 0xba, 0x57, 0x92, 0xd3, 0x8d, 0x69, 0xe7, 0x23, - 0x8f, 0xea, 0xf0, 0xf2, 0x4d, 0xde, 0x9d, 0x2a, - 0xab, 0x3a, 0x90, 0x10, 0x5f, 0x29, 0x19, 0x1a, - 0xf7, 0x02, 0x0a, 0x57, 0x3f, 0x39, 0x7a, 0xd9, - 0xf4, 0x75, 0x95, 0x6c, 0xce, 0x2e, 0xa1, 0xb9, - 0x0d, 0x78, 0x03, 0x42, 0xec, 0x5b, 0x60, 0xcb, - 0xb5, 0x06, 0xde, 0x6e, 0xec, 0x6e, 0x2d, 0x62, - 0x78, 0x1e, 0x8c, 0x40, 0x02, 0x52, 0xeb, 0xe9, - 0xe9, 0x39, 0xea, 0xee, 0x7f, 0xa0, 0x6c, 0x2e, - 0x93, 0x2a, 0xe4, 0xaf, 0x05, 0xa7, 0xa9, 0xc5, - 0x2a, 0x44, 0x6d, 0x5a, 0x46, 0x41, 0x03, 0x85, - 0x4c, 0x27, 0xb5, 0x83, 0xfd, 0xb9, 0xb9, 0x68, - 0x35, 0x26, 0xae, 0xcc, 0xca, 0x59, 0xa2, 0xe8, - 0x9d, 0xa5, 0xde, 0x90, 0x4f, 0xef, 0x8c, 0x92, - 0x11, 0x9f, 0x69, 0xd9, 0x66, 0x1c, 0xee, 0x83, - 0xe3, 0xe9, 0x60, 0x05, 0x0b, 0x43, 0x2b, 0x82, - 0xd7, 0x59, 0xdf, 0xb4, 0x1f, 0x19, 0x1b, 0xbe, - 0x30, 0x98, 0x71, 0x7e, 0xb9, 0xc0, 0xf5, 0xe2, - 0x08, 0xf4, 0x58, 0x42, 0x8a, 0x5b, 0xbb, 0x45, - 0xcf, 0x10, 0x89, 0xdf, 0xec, 0x97, 0x1a, 0x2f, - 0xac, 0xd7, 0xce, 0xd0, 0x62, 0x84, 0x6b, 0xa2, - 0xb6, 0xa8, 0x1b, 0xce, 0x7d, 0x68, 0xac, 0x31, - 0x30, 0x41, 0x09, 0x53, 0xaf, 0x53, 0x41, 0x8e, - 0xef, 0x34, 0x0f, 0x4a, 0xf2, 0xaa, 0x42, 0xc1, - 0x9e, 0x68, 0xf6, 0xda, 0xb0, 0x5d, 0xa8, 0x40, - 0xa5, 0x1f, 0x1d, 0x5f, 0x73, 0xfb, 0x2c, 0x82, - 0x42, 0x24, 0x70, 0xce, 0x30, 0x95, 0x69, 0xd1, - 0xed, 0xa5, 0xd9, 0xd0, 0xab, 0xb8, 0x9d, 0x8a, - 0x4d, 0xa0, 0x89, 0xb1, 0xaf, 0x93, 0x28, 0x59, - 0xfc, 0x6f, 0x5a, 0x97, 0x9a, 0xe9, 0x02, 0x8e, - 0xa1, 0x4e, 0x72, 0xde, 0x53, 0x5a, 0x0b, 0x42, - 0x72, 0x38, 0x41, 0x5f, 0x0c, 0x51, 0xac, 0xa8, - 0xb5, 0x17, 0x32, 0x1e, 0x18, 0xd6, 0x54, 0x67, - 0x0e, 0xc6, 0x43, 0xd0, 0xe0, 0xb6, 0xac, 0x40, - 0xfa, 0xaa, 0x76, 0xe3, 0x8d, 0xdb, 0x8a, 0x4a, - 0xa9, 0x09, 0xbb, 0x65, 0xd5, 0xca, 0xaa, 0xf5, - 0x0b, 0x63, 0xe0, 0x24, 0x79, 0x56, 0xd8, 0x1f, - 0x58, 0xc4, 0xc6, 0x31, 0x56, 0xfe, 0xba, 0xd6, - 0x85, 0xbd, 0x89, 0x92, 0x66, 0xff, 0xf1, 0xaf, - 0x52, 0x35, 0x1e, 0xa6, 0xa5, 0xcc, 0x9a, 0xc1, - 0x3b, 0x61, 0x72, 0x90, 0xaf, 0xab, 0x04, 0xbb, - 0xc0, 0x9a, 0xd1, 0xb9, 0xc0, 0x1b, 0x6b, 0xd0, - 0x6d, 0x95, 0x17, 0x43, 0x2b, 0x78, 0xaa, 0x52, - 0xc1, 0x57, 0x3f, 0xa5, 0xaa, 0x2d, 0xd7, 0x6c, - 0xf7, 0x97, 0x13, 0xb0, 0x99, 0xdb, 0x3f, 0xef, - 0xb8, 0xb0, 0xa6, 0x14, 0xbd, 0xea, 0xc2, 0x0a, - 0x84, 0x56, 0xf8, 0x2b, 0xa3, 0xdc, 0x48, 0xd1, - 0x75, 0xa2, 0xa8, 0x2a, 0xdc, 0xa8, 0x70, 0xe4, - 0xc1, 0x92, 0xb8, 0x71, 0x67, 0x51, 0x92, 0xbb, - 0x7d, 0xba, 0x78, 0xed, 0x93, 0x99, 0x0e, 0x56, - 0x2d, 0xe3, 0x43, 0x7d, 0xee, 0x02, 0x51, 0x15, - 0x64, 0x1e, 0x13, 0x04, 0xbb, 0xa0, 0xb4, 0x0c, - 0xb7, 0x30, 0xbb, 0x1f, 0x93, 0x30, 0x4e, 0x99, - 0xad, 0x4f, 0xce, 0x0b, 0xa1, 0x7f, 0xdf, 0x66, - 0x44, 0xb0, 0x49, 0x2c, 0x16, 0x9e, 0x22, 0x9b, - 0x88, 0xf0, 0x2b, 0x7d, 0xdd, 0x46, 0x50, 0x27, - 0xef, 0x61, 0x7b, 0xe2, 0xd8, 0xfd, 0x42, 0x10, - 0xeb, 0x07, 0xdf, 0x31, 0xf2, 0xb9, 0xab, 0xba, - 0x04, 0x95, 0xa7, 0xb3, 0x74, 0x71, 0xa8, 0x34, - 0x31, 0x95, 0xd6, 0x9a, 0x01, 0xd8, 0xab, 0x94, - 0xcc, 0x38, 0x8d, 0xb1, 0xa2, 0xe4, 0xeb, 0x86, - 0xbc, 0x84, 0x22, 0x23, 0xc2, 0xf3, 0x48, 0xaa, - 0xb9, 0x70, 0xd4, 0x20, 0x3c, 0xef, 0x61, 0xe2, - 0x10, 0x7c, 0x03, 0x6a, 0x8b, 0xab, 0x6b, 0xce, - 0xa2, 0x38, 0xaa, 0xc1, 0x43, 0x5c, 0x9b, 0x06, - 0x1e, 0x55, 0x13, 0x49, 0x36, 0x35, 0x6e, 0x10, - 0x56, 0xe2, 0x0c, 0xe2, 0x2f, 0xb9, 0x67, 0xc6, - 0xb0, 0x61, 0xd9, 0x1d, 0x81, 0xb9, 0x47, 0x64, - 0xd3, 0x7a, 0x55, 0x56, 0x6c, 0xf5, 0x15, 0xc8, - 0x23, 0xdc, 0x5f, 0xf9, 0xff, 0xba, 0x28, 0xe4, - }; - - memset(nonce, 0xEE, 16); - memset(key, 0x44, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, input_buf_caps); - uint8_t *plaintext = heap_caps_malloc(SZ, output_buf_caps); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - memset(plaintext, 0xAA, SZ); - - /* Test that all the end results are the same - no matter how many bytes we encrypt each call - */ - for (int bytes_to_process = 1; bytes_to_process < SZ; bytes_to_process++) { - ESP_LOGD("test", "bytes_to_process %d", bytes_to_process); - memset(nonce, 0xEE, 16); - memset(ciphertext, 0x0, SZ); - memset(decryptedtext, 0x0, SZ); - - size_t offset = 0; - // Encrypt - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = (idx + bytes_to_process > SZ) ? (SZ - idx) : bytes_to_process; - - mbedtls_aes_crypt_ctr(&ctx, length, &offset, nonce, - stream_block, plaintext + idx, ciphertext + idx ); - } - ESP_LOG_BUFFER_HEXDUMP("expected", expected_cipher, SZ, ESP_LOG_DEBUG); - ESP_LOG_BUFFER_HEXDUMP("actual ", ciphertext, SZ, ESP_LOG_DEBUG); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ); - - // Decrypt - memset(nonce, 0xEE, 16); - memset(decryptedtext, 0x22, SZ); - offset = 0; - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = (idx + bytes_to_process > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_aes_crypt_ctr(&ctx, length, &offset, nonce, - stream_block, ciphertext + idx, decryptedtext + idx ); - } - ESP_LOG_BUFFER_HEXDUMP("decrypted", decryptedtext, SZ, ESP_LOG_DEBUG); - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - } - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls CTR stream test", "[aes]") -{ - aes_ctr_stream_test(INTERNAL_DMA_CAPS, INTERNAL_DMA_CAPS, TEST_AES_CTR_STREAM_DMA_MODE_LEN); -} - -static void aes_ofb_stream_test(unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t iv[16]; - uint8_t key[16]; - - /* Cipher produced via this Python: - import os, binascii - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - from cryptography.hazmat.backends import default_backend - key = b'\x44' * 16 - iv = b'\xee' * 16 - cipher = Cipher(algorithms.AES(key), modes.OFB(iv), backend=default_backend()) - encryptor = cipher.encryptor() - ct = encryptor.update(b'\xaa' * 1000) + encryptor.finalize() - ct_arr = "" - for idx, b in enumerate(ct): - if idx % 8 == 0: - ct_arr += '\n' - ct_arr += "0x{}, ".format(format(b, '02x')) - print(ct_arr) - */ - const uint8_t expected_cipher[] = { - 0xc5, 0x78, 0xa7, 0xb4, 0xf3, 0xb9, 0xcb, 0x8b, - 0x09, 0xe0, 0xd6, 0x89, 0x14, 0x6a, 0x19, 0x09, - 0x0a, 0x33, 0x8b, 0xab, 0x82, 0xcb, 0x20, 0x8f, - 0x74, 0x2a, 0x6c, 0xb3, 0xc6, 0xe8, 0x18, 0x89, - 0x09, 0xb6, 0xaf, 0x20, 0xcd, 0xea, 0x74, 0x14, - 0x48, 0x61, 0xe8, 0x4d, 0x50, 0x12, 0x9f, 0x5e, - 0xb8, 0x10, 0x53, 0x3b, 0x74, 0xd9, 0xd0, 0x95, - 0x13, 0xdc, 0x14, 0xcf, 0x0c, 0xa1, 0x90, 0xfd, - 0xa2, 0x58, 0x12, 0xb2, 0x00, 0x2c, 0x5b, 0x7a, - 0x2a, 0x76, 0x80, 0x20, 0x82, 0x39, 0xa2, 0x21, - 0xf8, 0x7a, 0xec, 0xae, 0x82, 0x6a, 0x5c, 0xd3, - 0x04, 0xd9, 0xbd, 0xe4, 0x53, 0xc9, 0xdf, 0x67, - 0xaa, 0x5c, 0xaf, 0xa6, 0x95, 0x84, 0x01, 0xae, - 0x62, 0x24, 0xc7, 0xf5, 0x44, 0x30, 0x9b, 0xea, - 0xd5, 0x53, 0x62, 0xd6, 0x0d, 0x7a, 0x00, 0x19, - 0x86, 0xab, 0x97, 0x7d, 0x28, 0xa9, 0x08, 0xc8, - 0x5e, 0x20, 0x2c, 0x79, 0x24, 0x62, 0x45, 0x3e, - 0x4a, 0x3c, 0x34, 0x73, 0xd3, 0x84, 0xa1, 0xc7, - 0xee, 0x32, 0xe6, 0x29, 0xa7, 0x28, 0x8b, 0x23, - 0x90, 0x7a, 0x51, 0x3d, 0xac, 0x78, 0x08, 0x7a, - 0x9d, 0x01, 0x2e, 0xc4, 0x78, 0xd3, 0x58, 0x1d, - 0x9b, 0x66, 0x67, 0x89, 0x83, 0xfe, 0x28, 0x04, - 0x7e, 0x19, 0x2b, 0x2d, 0xbc, 0x23, 0x36, 0x58, - 0xef, 0x0a, 0x55, 0x8c, 0x8c, 0xa8, 0x70, 0xc6, - 0xd6, 0x60, 0xfa, 0x00, 0x61, 0x72, 0x28, 0x39, - 0xa7, 0xa7, 0x53, 0x26, 0x2b, 0x92, 0x2f, 0x44, - 0xa7, 0xb7, 0x69, 0x2c, 0x2a, 0xef, 0xf1, 0x1d, - 0x04, 0x9f, 0x39, 0x8c, 0xd1, 0x00, 0xf6, 0x93, - 0xdd, 0xe3, 0xd2, 0x7e, 0x68, 0x1a, 0xac, 0x51, - 0x21, 0x3a, 0xfb, 0x7d, 0x58, 0x00, 0x38, 0xa4, - 0xbc, 0xd6, 0x9b, 0xb0, 0xfd, 0x5b, 0x99, 0x40, - 0x0e, 0x35, 0x87, 0x22, 0x59, 0x80, 0xc6, 0x7c, - 0x06, 0x35, 0x22, 0x18, 0x0d, 0xdb, 0x40, 0x8a, - 0xe7, 0x8e, 0x13, 0x4a, 0x8f, 0xe7, 0xe6, 0x5c, - 0x88, 0x21, 0xfa, 0xc1, 0xf2, 0xb0, 0x1e, 0x4a, - 0x49, 0x6d, 0x9c, 0x28, 0x79, 0xa9, 0x2c, 0xea, - 0xb6, 0x14, 0xb0, 0xc9, 0x7a, 0xfe, 0x45, 0x2d, - 0xec, 0xbf, 0x65, 0x51, 0x50, 0x34, 0xf8, 0x25, - 0x7d, 0x47, 0x58, 0xc5, 0x65, 0x88, 0x57, 0x2e, - 0xa5, 0x10, 0xf2, 0xe9, 0x18, 0x2c, 0x90, 0x1e, - 0xb2, 0xf5, 0x4e, 0xd0, 0xd8, 0x02, 0xed, 0x90, - 0xbb, 0x9e, 0xa9, 0x79, 0xbc, 0x5c, 0x4f, 0xb9, - 0xe3, 0x47, 0x75, 0xbe, 0xa7, 0x21, 0xaf, 0x9a, - 0x40, 0xc3, 0x86, 0x34, 0x0d, 0x06, 0xb6, 0x12, - 0xbf, 0x12, 0xee, 0x79, 0xdb, 0xca, 0x44, 0x1f, - 0xc6, 0x6d, 0xab, 0xa7, 0x9c, 0x37, 0x50, 0x5a, - 0x49, 0xff, 0xb4, 0xcf, 0x72, 0xb1, 0x47, 0xd2, - 0xaa, 0xbc, 0xb4, 0xd4, 0xb3, 0x5b, 0xdd, 0x16, - 0x76, 0xc1, 0x85, 0xd0, 0x7d, 0x1a, 0x27, 0xe4, - 0xc8, 0x7b, 0x30, 0x32, 0x5b, 0x6e, 0x51, 0x2d, - 0x00, 0x5a, 0x47, 0x80, 0xdb, 0xe9, 0x07, 0xff, - 0x63, 0xf1, 0x8b, 0xd3, 0x5a, 0xf5, 0xf4, 0x5b, - 0x6c, 0xba, 0x8e, 0x9e, 0x3c, 0x6e, 0x6e, 0xf6, - 0x0f, 0xc9, 0x42, 0xc9, 0xf9, 0x74, 0x87, 0x86, - 0xeb, 0x36, 0x01, 0x69, 0xa4, 0xae, 0x11, 0xfb, - 0x95, 0x7f, 0xe1, 0xc5, 0x6f, 0xe6, 0xe5, 0xfa, - 0x01, 0xb2, 0x82, 0x17, 0x41, 0x2f, 0x91, 0xb0, - 0x99, 0xbd, 0xfb, 0x38, 0xab, 0x7c, 0x31, 0xcf, - 0x7d, 0xbf, 0xb5, 0xee, 0xb0, 0x1c, 0x84, 0x0b, - 0xbc, 0xcd, 0xfa, 0x6f, 0xdb, 0xc1, 0x4d, 0x87, - 0xe7, 0x0a, 0xaf, 0x6b, 0xd3, 0xfc, 0xe0, 0x88, - 0xdc, 0xa5, 0x66, 0xe9, 0x94, 0xd0, 0x3e, 0x00, - 0xc8, 0xf6, 0xc2, 0x2d, 0x00, 0xbf, 0x09, 0x30, - 0xe5, 0x4f, 0xe7, 0x6b, 0x6b, 0x78, 0x68, 0xb6, - 0x9a, 0x45, 0x44, 0x37, 0x18, 0x77, 0xe4, 0xe1, - 0xb4, 0x5d, 0x74, 0x9e, 0xef, 0xaf, 0xe0, 0x10, - 0x48, 0x06, 0xff, 0xcc, 0xb2, 0x7b, 0xbc, 0x40, - 0x64, 0x94, 0x37, 0x60, 0x52, 0xaa, 0xe0, 0xad, - 0xf4, 0x05, 0xf9, 0x24, 0x1b, 0xf1, 0x46, 0x47, - 0x07, 0x42, 0xa4, 0xa6, 0x09, 0x04, 0x71, 0xa6, - 0x8d, 0x42, 0x2a, 0x38, 0x1b, 0x7d, 0xb9, 0x84, - 0xcd, 0xa1, 0x0d, 0x96, 0x11, 0xdb, 0x08, 0xe9, - 0x63, 0x39, 0xf8, 0x91, 0x26, 0x03, 0x01, 0x13, - 0xfb, 0xb2, 0xb6, 0xe5, 0xe0, 0xab, 0x65, 0x1b, - 0xc2, 0x99, 0x16, 0xd7, 0x74, 0xd6, 0x70, 0x39, - 0x43, 0x0e, 0xff, 0x62, 0xcc, 0x46, 0xba, 0x62, - 0x15, 0xba, 0xa8, 0x9d, 0xe6, 0x9d, 0x7b, 0xbc, - 0xfa, 0xb2, 0xde, 0xc5, 0x7a, 0xa2, 0x7a, 0x5f, - 0x1f, 0x66, 0x45, 0x2e, 0x1c, 0xfc, 0xc2, 0x53, - 0xfd, 0x7f, 0x1c, 0x14, 0x42, 0x91, 0x84, 0xea, - 0xaf, 0x6d, 0x95, 0x12, 0x71, 0xbf, 0x5f, 0xf2, - 0x68, 0x05, 0xa6, 0xa8, 0xcb, 0x6e, 0x07, 0x58, - 0xdb, 0xdc, 0x4d, 0x6c, 0x51, 0xa9, 0xe0, 0x93, - 0x7d, 0x00, 0x15, 0x27, 0x13, 0x62, 0x7c, 0xab, - 0x84, 0xf0, 0xbb, 0xb9, 0x50, 0x67, 0x96, 0x9d, - 0x48, 0xe3, 0x43, 0x5f, 0x8d, 0x1d, 0xf4, 0x03, - 0x58, 0xf1, 0xcb, 0x67, 0x6f, 0x5e, 0xb3, 0x4c, - 0x1f, 0x57, 0x9b, 0x29, 0xa6, 0x9b, 0xef, 0x39, - 0xf0, 0xa4, 0x85, 0x1b, 0x59, 0x51, 0x8a, 0x69, - 0x44, 0xcc, 0xeb, 0xf9, 0xf0, 0x01, 0xac, 0xdf, - 0x28, 0xdf, 0x46, 0x2a, 0x50, 0x57, 0xca, 0x21, - 0x93, 0x00, 0x9f, 0x3b, 0xed, 0x72, 0x9b, 0x37, - 0xcf, 0x6a, 0x8b, 0x6c, 0xe7, 0x59, 0xb5, 0x13, - 0x1f, 0x29, 0xf7, 0x89, 0x2d, 0xf4, 0x10, 0xdc, - 0x5d, 0x3e, 0xee, 0x01, 0x5e, 0x62, 0x62, 0xec, - 0x1b, 0x89, 0x2d, 0x3b, 0x9b, 0x5e, 0x48, 0x74, - 0xd4, 0xba, 0x78, 0xf4, 0xfa, 0xfb, 0x4c, 0x3b, - 0xa5, 0xb7, 0x69, 0xb0, 0x36, 0x68, 0xcd, 0x98, - 0xc9, 0x3f, 0x6a, 0x20, 0x10, 0xf6, 0x11, 0x2e, - 0x6d, 0x88, 0x37, 0x77, 0x92, 0xa3, 0x70, 0x16, - 0x41, 0x8c, 0x5f, 0x4a, 0x6f, 0x27, 0x50, 0x07, - 0x7e, 0xc5, 0x04, 0x27, 0xb3, 0xc3, 0x7d, 0xf6, - 0xe1, 0x04, 0xdd, 0xe3, 0xb9, 0xf7, 0x02, 0x74, - 0x5c, 0x00, 0xeb, 0xb5, 0x46, 0x19, 0x36, 0x6a, - 0x23, 0xd6, 0x1d, 0x2d, 0xee, 0xa5, 0x0f, 0x20, - 0x9d, 0xfa, 0x76, 0x57, 0x22, 0x17, 0xfa, 0x5a, - 0x5d, 0x63, 0x85, 0x46, 0x43, 0x10, 0xc2, 0xa7, - 0x05, 0x8c, 0x41, 0x14, 0x0c, 0xa1, 0xdf, 0x26, - 0xee, 0xd3, 0xc7, 0x06, 0x45, 0x54, 0xe3, 0xc5, - 0x7f, 0xfd, 0x52, 0xc3, 0xe8, 0xf9, 0x3a, 0x96, - 0xd7, 0x32, 0x38, 0xa9, 0xd3, 0x7e, 0x15, 0x16, - 0x3e, 0xcd, 0xcf, 0xd2, 0xea, 0x01, 0xd4, 0xc6, - 0x3a, 0x01, 0x4d, 0x0f, 0x64, 0xf9, 0xc1, 0xe0, - 0xf4, 0xcd, 0xc0, 0xe8, 0x50, 0x4f, 0x79, 0xb9, - 0x79, 0xae, 0x15, 0x1e, 0x6d, 0xf9, 0x2a, 0xca, - 0x37, 0x79, 0x34, 0x2b, 0x96, 0x18, 0x2c, 0x88, - 0x3f, 0x2b, 0xf1, 0x8d, 0x6d, 0x56, 0x60, 0xe8, - 0x36, 0x48, 0x0c, 0x0b, 0x78, 0x79, 0x71, 0x67, - 0xf2, 0x35, 0x2d, 0x4c, 0xf2, 0x9f, 0xc7, 0xce, - 0x4d, 0x36, 0x92, 0xeb, 0x81, 0x30, 0xac, 0xcf, - 0xbc, 0x34, 0x13, 0x42, 0x39, 0x74, 0x8f, 0x23, - 0x77, 0xd3, 0x2b, 0x7e, 0xd3, 0x5d, 0x0c, 0x36, - 0x73, 0x4b, 0x09, 0xb2, 0xc9, 0xd2, 0xd2, 0x07, - 0xda, 0xbd, 0x8f, 0x78, 0xb8, 0xdf, 0x29, 0xdb, - 0xe4, 0xbf, 0xcd, 0x23, 0x2f, 0x7a, 0x58, 0x86, - }; - - memset(key, 0x44, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - memset(plaintext, 0xAA, SZ); - - /* Test that all the end results are the same - no matter how many bytes we encrypt each call - */ - - for (int bytes_to_process = 1; bytes_to_process < SZ; bytes_to_process++) { - ESP_LOGD("test", "bytes_to_process %d", bytes_to_process); - // Encrypt - memset(iv, 0xEE, 16); - size_t offset = 0; - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = ( (idx + bytes_to_process) > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_aes_crypt_ofb(&ctx, length, &offset, iv, plaintext + idx, ciphertext + idx); - - } - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ); - - // Decrypt - memset(iv, 0xEE, 16); - memset(decryptedtext, 0x22, SZ); - offset = 0; - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = (idx + bytes_to_process > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_aes_crypt_ofb(&ctx, length, &offset, iv, ciphertext + idx, decryptedtext + idx); - } - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - } - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls OFB stream test", "[aes]") -{ - aes_ofb_stream_test(TEST_AES_OFB_STREAM_DMA_MODE_LEN); -} - -static void aes_cfb8_stream_test(unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t iv[16]; - uint8_t key[16]; - - /* Cipher produced via this Python: - import os, binascii - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - from cryptography.hazmat.backends import default_backend - key = b'\x44' * 16 - iv = b'\xee' * 16 - cipher = Cipher(algorithms.AES(key), modes.CFB8(iv), backend=default_backend()) - encryptor = cipher.encryptor() - ct = encryptor.update(b'\xaa' * 1000) + encryptor.finalize() - ct_arr = "" - for idx, b in enumerate(ct): - if idx % 8 == 0: - ct_arr += '\n' - ct_arr += "0x{}, ".format(format(b, '02x')) - print(ct_arr) - */ - const uint8_t expected_cipher[] = { - 0xc5, 0x2f, 0xb0, 0x9b, 0x94, 0x9c, 0xa4, 0x5c, - 0x0f, 0x4d, 0xa1, 0x9d, 0xd1, 0x19, 0xfc, 0x04, - 0xe2, 0x7f, 0x04, 0x82, 0x6a, 0xa3, 0x61, 0xbb, - 0x07, 0x6f, 0xac, 0xb9, 0xdf, 0x00, 0xf9, 0xa8, - 0xc4, 0xbe, 0x9d, 0x4d, 0xd9, 0x42, 0x8a, 0x83, - 0x12, 0x8b, 0xeb, 0xd7, 0x88, 0x70, 0x8a, 0xed, - 0x46, 0x81, 0x5b, 0x4c, 0x14, 0x67, 0xe0, 0xfb, - 0xab, 0x34, 0x90, 0x85, 0x24, 0xd2, 0x6b, 0x64, - 0xdf, 0x1d, 0x04, 0xfd, 0x69, 0xf6, 0x30, 0xbe, - 0xa6, 0xac, 0x0b, 0x54, 0x25, 0x24, 0x67, 0xd6, - 0x09, 0xb1, 0x8f, 0x91, 0x63, 0xbd, 0xdf, 0xa1, - 0x8a, 0xa3, 0x2e, 0xeb, 0x15, 0x7d, 0xe5, 0x37, - 0xe5, 0x5a, 0x9f, 0xa5, 0x21, 0xc2, 0xbd, 0xd6, - 0x05, 0xed, 0xf3, 0xbe, 0xe4, 0xf2, 0x8c, 0xd6, - 0x6a, 0xae, 0x1e, 0x3d, 0x7a, 0x5f, 0xf1, 0x1f, - 0x95, 0xe9, 0x6d, 0xbf, 0x14, 0x56, 0x2f, 0x7f, - 0x4e, 0x0d, 0xc7, 0xf0, 0x81, 0x50, 0xca, 0x58, - 0xe4, 0xe3, 0xf0, 0xa7, 0x38, 0x45, 0xfb, 0xc1, - 0xf0, 0x6e, 0xb1, 0x94, 0x08, 0x29, 0xf1, 0x7d, - 0x6f, 0x97, 0x14, 0xb5, 0x2b, 0x6d, 0x9d, 0x6a, - 0x52, 0xc8, 0xd6, 0x64, 0xe4, 0x79, 0x40, 0x8c, - 0x9d, 0x40, 0x81, 0xf0, 0x68, 0xc8, 0xce, 0x4e, - 0xcf, 0xf5, 0xdc, 0x05, 0x49, 0x7c, 0x7c, 0x72, - 0x36, 0xe9, 0x1a, 0x72, 0x15, 0x9c, 0x9a, 0xc4, - 0x62, 0xba, 0xa5, 0xbe, 0xf6, 0x4e, 0x29, 0x6d, - 0xe0, 0xe1, 0x41, 0xbd, 0x7d, 0x7d, 0xe5, 0xbe, - 0xaf, 0xd3, 0x85, 0xb7, 0x0e, 0x7a, 0xd7, 0xe7, - 0xf4, 0xeb, 0x28, 0xd3, 0xa2, 0xf9, 0x30, 0x9b, - 0xe7, 0x61, 0x6b, 0x7c, 0x13, 0x98, 0xa6, 0xc8, - 0xdc, 0xd1, 0xcf, 0x9d, 0xfa, 0xf8, 0xdc, 0x89, - 0xe7, 0xdc, 0x27, 0x38, 0x94, 0x7a, 0x76, 0x49, - 0xe3, 0xfe, 0x3e, 0xc1, 0xc7, 0x95, 0x07, 0x48, - 0x33, 0xf7, 0x54, 0x24, 0x21, 0xc0, 0x86, 0xc5, - 0xcf, 0xd4, 0x67, 0x18, 0x31, 0x5d, 0xb0, 0x40, - 0x7f, 0x37, 0xb7, 0x01, 0xf6, 0x93, 0xbf, 0x4f, - 0x65, 0x19, 0x03, 0xf3, 0x4f, 0x7a, 0x84, 0x13, - 0x4b, 0x3d, 0x4c, 0x83, 0x58, 0xce, 0xe3, 0x84, - 0xf5, 0xea, 0xe2, 0x24, 0x91, 0x04, 0xd9, 0x96, - 0x47, 0x15, 0xdd, 0xfe, 0xae, 0xc3, 0x88, 0xe6, - 0x23, 0xbf, 0x57, 0x9c, 0x46, 0x07, 0xf4, 0x32, - 0x88, 0xb3, 0x99, 0x93, 0xd9, 0x0c, 0x5d, 0x39, - 0xba, 0x7d, 0xd1, 0x92, 0x3c, 0x3c, 0x69, 0xe1, - 0xcc, 0xb2, 0x5f, 0x76, 0x10, 0xd2, 0x9e, 0x60, - 0xb1, 0x5a, 0x1c, 0x9f, 0x88, 0xb1, 0x27, 0xeb, - 0x89, 0x59, 0x29, 0xaa, 0x8f, 0x8c, 0x57, 0x2d, - 0xc8, 0x3e, 0x07, 0xd4, 0x1b, 0x11, 0x6a, 0x7a, - 0x5d, 0x29, 0xf6, 0x56, 0xe2, 0x8f, 0x12, 0xcf, - 0x33, 0x79, 0x02, 0xf2, 0x3b, 0xc2, 0x8f, 0x0d, - 0x02, 0x47, 0xba, 0xdd, 0x55, 0x1f, 0x41, 0x71, - 0x08, 0x1c, 0x9e, 0xa7, 0x79, 0xec, 0x49, 0xf3, - 0x33, 0x2a, 0x09, 0xa8, 0xe6, 0xba, 0x1c, 0xa9, - 0x0f, 0x67, 0xda, 0xc3, 0xec, 0x3c, 0x22, 0xc1, - 0xf5, 0x54, 0x3b, 0x40, 0xdc, 0x47, 0xb8, 0x53, - 0x35, 0x55, 0x1c, 0xa3, 0x76, 0x36, 0x77, 0xe2, - 0xe8, 0x97, 0x25, 0x20, 0x71, 0x39, 0x35, 0x71, - 0x80, 0x35, 0xda, 0x64, 0xab, 0x3c, 0xd1, 0x94, - 0x1d, 0xca, 0x55, 0x83, 0xad, 0xe2, 0xed, 0xb8, - 0x3f, 0xa4, 0x5d, 0xb2, 0xcc, 0x01, 0x90, 0x02, - 0x81, 0xe6, 0xc1, 0x1c, 0x4e, 0x17, 0x32, 0x9f, - 0xdb, 0x24, 0x24, 0x8f, 0x60, 0x71, 0xe2, 0xba, - 0x15, 0x1b, 0x83, 0x7a, 0xdb, 0x21, 0x7d, 0x0b, - 0x67, 0xec, 0xa3, 0xf0, 0x5e, 0xe2, 0xd2, 0x80, - 0xa8, 0x77, 0x4f, 0x7a, 0xf3, 0xb9, 0xef, 0x68, - 0x34, 0xfe, 0x3b, 0x4f, 0x6b, 0xbc, 0xdf, 0x32, - 0x68, 0xc5, 0xea, 0xb5, 0xcf, 0xe3, 0x33, 0xbf, - 0xc7, 0x57, 0xd9, 0x12, 0xa4, 0x2a, 0x09, 0x81, - 0x4e, 0x1b, 0x8c, 0xd9, 0x58, 0x15, 0x5d, 0xe1, - 0xef, 0x13, 0xe7, 0x35, 0xb1, 0x32, 0x00, 0x74, - 0x68, 0x2d, 0x7d, 0x5d, 0xd2, 0xce, 0x72, 0xd6, - 0xe1, 0x67, 0x98, 0xed, 0xfb, 0x0e, 0xee, 0xe8, - 0x9a, 0x0a, 0x57, 0x87, 0xe7, 0x1f, 0xc0, 0xa8, - 0x4a, 0x6a, 0x32, 0x8c, 0x98, 0x72, 0x89, 0x29, - 0xfe, 0xf7, 0x30, 0x7a, 0xa3, 0xd7, 0xcc, 0xa8, - 0x0b, 0x84, 0xf7, 0xfb, 0x58, 0x05, 0x84, 0xa4, - 0xf6, 0x73, 0x5e, 0x5f, 0xb3, 0x9e, 0xa1, 0x24, - 0x8b, 0xd7, 0x2c, 0xbc, 0x9c, 0x0c, 0x17, 0xe2, - 0xac, 0x6a, 0xce, 0x8e, 0x24, 0x56, 0x97, 0x9b, - 0xd4, 0xd8, 0x52, 0x92, 0x3c, 0x23, 0x4b, 0x90, - 0x0c, 0x6c, 0x7c, 0xa4, 0x8f, 0xee, 0xd1, 0x14, - 0x3a, 0x82, 0xae, 0xf2, 0x23, 0xfc, 0xfa, 0x29, - 0x43, 0x9e, 0xa9, 0x8e, 0xd9, 0xa3, 0x37, 0x64, - 0xbe, 0x50, 0x49, 0x34, 0x92, 0x1b, 0x7e, 0x06, - 0x85, 0x51, 0x7f, 0x21, 0x19, 0xa1, 0x9a, 0xfd, - 0x95, 0x76, 0xfd, 0x80, 0x79, 0xdb, 0x40, 0xe2, - 0x6d, 0xfb, 0x38, 0xe9, 0xe4, 0x6d, 0x65, 0x6d, - 0x1f, 0x97, 0x6c, 0x06, 0x3f, 0xee, 0x5b, 0x9a, - 0x85, 0x19, 0xeb, 0xae, 0x65, 0x68, 0x90, 0xa7, - 0xb7, 0x47, 0x0c, 0x08, 0xc6, 0x8f, 0x37, 0x00, - 0xde, 0xe5, 0x3e, 0xe1, 0x60, 0x88, 0x0d, 0x85, - 0x50, 0x30, 0xf2, 0x68, 0x79, 0x39, 0x37, 0xe9, - 0x0c, 0x3f, 0xdd, 0x88, 0x83, 0x3a, 0x00, 0x80, - 0xd4, 0x16, 0x06, 0x84, 0x18, 0xa0, 0x2c, 0x04, - 0x17, 0xae, 0x6a, 0x36, 0x38, 0xe1, 0x40, 0xb0, - 0xfb, 0x77, 0x8f, 0xee, 0x24, 0xe5, 0x5e, 0xec, - 0xa8, 0x7a, 0x0a, 0xec, 0xf9, 0x3d, 0x45, 0x77, - 0x0f, 0x9c, 0x67, 0xa1, 0xc8, 0x80, 0xb8, 0x7e, - 0x41, 0x9b, 0x49, 0x43, 0x7a, 0x06, 0x76, 0x5b, - 0x6e, 0x48, 0xdd, 0x66, 0xc6, 0x4b, 0x55, 0x2f, - 0x45, 0x73, 0xa4, 0x84, 0xbe, 0xcb, 0xe9, 0xc9, - 0x70, 0xbf, 0x54, 0x79, 0x0a, 0x29, 0x2b, 0xa3, - 0x95, 0xe8, 0x08, 0xc7, 0xb2, 0x92, 0x57, 0x6c, - 0x73, 0x3e, 0xe8, 0xff, 0xf7, 0x64, 0x61, 0x89, - 0x68, 0x7e, 0x0c, 0xc7, 0xc3, 0x21, 0xea, 0xcc, - 0x34, 0xda, 0x10, 0x0f, 0x10, 0x35, 0x4c, 0xbf, - 0x1c, 0xa2, 0x3b, 0x1a, 0xba, 0x1c, 0x1d, 0xc3, - 0x1e, 0xb8, 0x7a, 0xf2, 0x7d, 0x31, 0x1d, 0x83, - 0xce, 0x3b, 0x5c, 0x5a, 0x03, 0xe3, 0xfc, 0x9a, - 0xfe, 0xaa, 0x3c, 0xf9, 0x9f, 0x60, 0x7c, 0x54, - 0x02, 0x70, 0x23, 0xdb, 0x23, 0xe7, 0x4d, 0x5b, - 0x41, 0x8c, 0x1b, 0x01, 0xc9, 0x8e, 0x41, 0xb3, - 0xb9, 0x61, 0x90, 0xc1, 0x2b, 0xc5, 0xfa, 0xcf, - 0x05, 0x4d, 0xe0, 0x1a, 0x9f, 0xc3, 0xa3, 0x6c, - 0x81, 0x4c, 0x6a, 0x33, 0x8f, 0x74, 0x71, 0x79, - 0x5d, 0x30, 0x62, 0x03, 0xaa, 0x52, 0x61, 0x0d, - 0xaf, 0xf7, 0xe1, 0x80, 0x5b, 0x97, 0x30, 0x6d, - 0x31, 0x21, 0xc1, 0x02, 0x43, 0x99, 0x2b, 0x49, - 0xe9, 0x83, 0x5d, 0x24, 0x40, 0x5a, 0xcd, 0x2f, - 0x20, 0xe4, 0x69, 0x7a, 0x22, 0xcf, 0x1d, 0xb2, - 0x90, 0x2d, 0xda, 0x42, 0xf8, 0xb3, 0x8a, 0x3d, - 0x55, 0x5a, 0xc5, 0x0f, 0x12, 0x25, 0x3d, 0x98, - 0xa1, 0x83, 0xd3, 0x3b, 0xa5, 0xe1, 0x36, 0x2f, - 0x85, 0xe1, 0x4b, 0x48, 0x5e, 0xe7, 0xc1, 0x57, - 0x19, 0xca, 0xc0, 0xc0, 0x23, 0x59, 0x06, 0xb6, - 0x32, 0xeb, 0x9e, 0x2b, 0xf5, 0x23, 0x5a, 0x90, - 0xfc, 0x6d, 0xd1, 0xcd, 0x3a, 0x93, 0xdd, 0xc2, - }; - - memset(key, 0x44, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - memset(plaintext, 0xAA, SZ); - - /* Test that all the end results are the same - no matter how many bytes we encrypt each call - */ - - for (int bytes_to_process = 1; bytes_to_process < SZ; bytes_to_process++) { - memset(iv, 0xEE, 16); - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = ( (idx + bytes_to_process) > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_aes_crypt_cfb8(&ctx, MBEDTLS_AES_ENCRYPT, length, iv, plaintext + idx, ciphertext + idx); - - } - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ); - - memset(iv, 0xEE, 16); - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = ( (idx + bytes_to_process) > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_aes_crypt_cfb8(&ctx, MBEDTLS_AES_DECRYPT, length, iv, ciphertext + idx, decryptedtext + idx); - - } - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - } - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls CFB8 stream test", "[aes]") -{ - aes_cfb8_stream_test(TEST_AES_CFB8_STREAM_DMA_MODE_LEN); -} - -static void aes_cfb128_stream_test(unsigned int SZ) -{ - mbedtls_aes_context ctx; - uint8_t iv[16]; - uint8_t key[16]; - - /* Cipher produced via this Python: - import os, binascii - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - from cryptography.hazmat.backends import default_backend - key = b'\x44' * 16 - iv = b'\xee' * 16 - cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=default_backend()) - encryptor = cipher.encryptor() - ct = encryptor.update(b'\xaa' * 1000) + encryptor.finalize() - ct_arr = "" - for idx, b in enumerate(ct): - if idx % 8 == 0: - ct_arr += '\n' - ct_arr += "0x{}, ".format(format(b, '02x')) - print(ct_arr) - */ - const uint8_t expected_cipher[] = { - 0xc5, 0x78, 0xa7, 0xb4, 0xf3, 0xb9, 0xcb, 0x8b, - 0x09, 0xe0, 0xd6, 0x89, 0x14, 0x6a, 0x19, 0x09, - 0xf9, 0x08, 0x7e, 0xe1, 0x92, 0x8a, 0x7c, 0xa4, - 0x25, 0xa5, 0xa7, 0x43, 0x24, 0x8d, 0x85, 0x3e, - 0x99, 0x28, 0xeb, 0x36, 0x59, 0x74, 0x69, 0x0e, - 0x09, 0x9f, 0x4e, 0xc0, 0x6d, 0xc3, 0x2b, 0x80, - 0x01, 0xad, 0xa1, 0x0c, 0x99, 0x90, 0x8b, 0x07, - 0xd6, 0x00, 0xf0, 0x32, 0xd7, 0x6b, 0xa1, 0xf1, - 0x4d, 0x14, 0xd0, 0x28, 0xde, 0x64, 0x23, 0x71, - 0xf4, 0x23, 0x61, 0x12, 0x71, 0xbe, 0x03, 0x74, - 0x99, 0x81, 0x9d, 0x65, 0x48, 0xd9, 0xd4, 0x67, - 0xd1, 0x31, 0xe8, 0x44, 0x27, 0x17, 0xd4, 0x2d, - 0x3d, 0x59, 0xf7, 0xd3, 0x9a, 0x7a, 0x82, 0xac, - 0x6d, 0x78, 0xad, 0xae, 0x07, 0x41, 0xec, 0xce, - 0x55, 0xad, 0x97, 0x1a, 0x2c, 0x87, 0xc6, 0xa1, - 0x4e, 0x25, 0xe7, 0xbd, 0x2d, 0xa4, 0x62, 0xb9, - 0xa1, 0xc4, 0xf2, 0xb3, 0xae, 0x6a, 0x47, 0x06, - 0x5b, 0x18, 0xcc, 0x58, 0x5a, 0x37, 0x8a, 0xe2, - 0x7c, 0x87, 0x77, 0x10, 0xd1, 0xec, 0xbc, 0x5a, - 0xbd, 0xb8, 0x66, 0x20, 0x90, 0xb6, 0x82, 0x53, - 0xe3, 0x7d, 0xbb, 0x68, 0xa0, 0x51, 0x40, 0x1c, - 0x16, 0x66, 0x9a, 0x48, 0xf2, 0xc5, 0xe9, 0xe1, - 0xc2, 0xa9, 0x09, 0xda, 0xa9, 0x75, 0xee, 0xfa, - 0x4e, 0xe0, 0x72, 0x3c, 0x2e, 0x4f, 0xb4, 0x76, - 0x0d, 0x7c, 0x38, 0x36, 0x14, 0xa4, 0x41, 0x90, - 0xc1, 0x65, 0x98, 0x16, 0x73, 0xae, 0x63, 0x6f, - 0x7d, 0xba, 0x25, 0x7c, 0x86, 0x5c, 0x1e, 0x2f, - 0x72, 0x67, 0xfb, 0xe9, 0xd4, 0xad, 0x89, 0x48, - 0x0c, 0xd7, 0x5a, 0xe1, 0x92, 0xf9, 0xc9, 0x8e, - 0xe3, 0x64, 0xcd, 0x20, 0xd8, 0xec, 0x95, 0x39, - 0x78, 0xdb, 0xac, 0x5b, 0xb0, 0x38, 0x13, 0xee, - 0xfe, 0xec, 0x1e, 0x2e, 0xe3, 0x57, 0xc1, 0x04, - 0x7a, 0xee, 0x1b, 0xbc, 0x85, 0x71, 0x26, 0x51, - 0xfb, 0x1d, 0xe4, 0xfb, 0x29, 0x2c, 0xd0, 0x12, - 0x94, 0xcf, 0x2b, 0x01, 0x7f, 0xb4, 0x95, 0x0c, - 0xc6, 0x3c, 0x3b, 0x31, 0x2e, 0x1d, 0x39, 0x85, - 0x50, 0x20, 0x70, 0x68, 0x25, 0x7e, 0xeb, 0xd6, - 0x77, 0xd0, 0x66, 0x0d, 0xd0, 0x69, 0x12, 0x8f, - 0x00, 0x77, 0xd4, 0xcd, 0xcc, 0xd9, 0xd1, 0x1c, - 0x77, 0xf9, 0x57, 0xca, 0xdf, 0x73, 0x90, 0xad, - 0x6e, 0xb7, 0xd8, 0x96, 0x58, 0xc7, 0x7d, 0xd3, - 0x41, 0xb1, 0x74, 0x9f, 0xae, 0x2f, 0x8d, 0x25, - 0xd4, 0xb1, 0xe8, 0xcb, 0x77, 0xe9, 0xb5, 0x57, - 0xfb, 0xc7, 0x4b, 0x06, 0x4f, 0x61, 0xcd, 0x2c, - 0xfe, 0x46, 0x93, 0x2f, 0x60, 0x02, 0x68, 0xe4, - 0x07, 0x85, 0x59, 0x39, 0x07, 0x5d, 0x2f, 0x13, - 0xa3, 0x29, 0x04, 0xab, 0x21, 0xb2, 0x35, 0x8a, - 0xd6, 0xc1, 0x1c, 0x0c, 0xb6, 0x4b, 0x0e, 0x67, - 0xdc, 0xc8, 0xb3, 0x5f, 0x43, 0xde, 0xba, 0x05, - 0xe4, 0xbd, 0xa9, 0xf3, 0x28, 0x67, 0x23, 0x24, - 0x6e, 0x7a, 0xac, 0xce, 0x2b, 0x58, 0x2f, 0xfc, - 0xe8, 0x3e, 0x0b, 0x51, 0x4c, 0xd7, 0x8a, 0xdf, - 0xa8, 0x5a, 0xeb, 0x45, 0xf1, 0x4a, 0x57, 0x0a, - 0x8c, 0xf5, 0x58, 0x7e, 0xb9, 0x1b, 0x11, 0x48, - 0x75, 0x7c, 0x2c, 0x07, 0x31, 0x96, 0x8b, 0xab, - 0x2a, 0x0b, 0x97, 0x6b, 0x59, 0x70, 0xdb, 0x3f, - 0xf0, 0x68, 0xd2, 0x29, 0xef, 0x1a, 0x65, 0x09, - 0xf1, 0x06, 0xc9, 0xd7, 0x68, 0x8d, 0x97, 0x17, - 0x68, 0x5d, 0xdc, 0x62, 0xe9, 0xbb, 0x47, 0xa6, - 0x92, 0x32, 0xb3, 0x1e, 0x5c, 0x81, 0xc6, 0x54, - 0x41, 0xa8, 0xa2, 0x71, 0x3c, 0xf2, 0x48, 0xd3, - 0x4b, 0x23, 0x9d, 0x46, 0x10, 0x90, 0xda, 0xae, - 0x67, 0x3b, 0x21, 0xe2, 0xde, 0x79, 0x29, 0x32, - 0x35, 0x58, 0x15, 0x0c, 0xc3, 0xbf, 0x67, 0xbb, - 0x91, 0x06, 0x6c, 0x7a, 0xb4, 0x58, 0xe1, 0x29, - 0x38, 0xe3, 0xda, 0x66, 0x93, 0x38, 0x42, 0xd3, - 0x01, 0xc0, 0xe7, 0x4d, 0x0c, 0x66, 0x4b, 0x8b, - 0xae, 0x16, 0xba, 0xc4, 0xdb, 0xce, 0x92, 0x2b, - 0x88, 0xed, 0xb2, 0x59, 0xd4, 0x2a, 0x0f, 0x7a, - 0x3a, 0xce, 0xe0, 0xab, 0xa3, 0x46, 0xe4, 0x2b, - 0xd9, 0x0b, 0x14, 0x06, 0xc0, 0x7a, 0xe6, 0x40, - 0x23, 0x5d, 0x4d, 0x57, 0x9f, 0xfc, 0x7e, 0x08, - 0xfc, 0x52, 0x3d, 0x07, 0xd8, 0xee, 0xfa, 0x7c, - 0x2a, 0xbc, 0x93, 0x76, 0x7a, 0xc1, 0x32, 0x7a, - 0xd7, 0x52, 0xc4, 0x29, 0xec, 0x6b, 0x3b, 0x6d, - 0xc8, 0x63, 0xc5, 0x93, 0x60, 0x0a, 0x7d, 0x37, - 0x2e, 0x6c, 0xb0, 0x48, 0xe8, 0x47, 0xa5, 0x6a, - 0x9d, 0x75, 0x15, 0xf5, 0xfb, 0x89, 0x44, 0xf6, - 0x4c, 0x93, 0xc6, 0xdd, 0xe1, 0x72, 0xc3, 0xb9, - 0x77, 0xdf, 0x89, 0xed, 0x01, 0xb0, 0x4f, 0x6d, - 0xcf, 0x80, 0xf3, 0x03, 0xb4, 0xca, 0x58, 0xc8, - 0x55, 0x89, 0x91, 0x64, 0x66, 0xd5, 0xbe, 0x92, - 0xf0, 0x6b, 0xa3, 0xa9, 0xfd, 0x13, 0x31, 0xc2, - 0x6d, 0xab, 0xf0, 0xac, 0xce, 0x8c, 0x9d, 0xda, - 0x33, 0x97, 0x80, 0x9e, 0x9f, 0xcd, 0x57, 0xde, - 0x51, 0x78, 0x2b, 0xc8, 0xe7, 0xe4, 0x46, 0x3a, - 0x40, 0x16, 0xd1, 0xe0, 0xb5, 0xe8, 0x47, 0xfc, - 0x39, 0x0d, 0x68, 0x41, 0x26, 0x08, 0xdb, 0x3f, - 0xf1, 0x54, 0xf1, 0x7e, 0xc8, 0xa9, 0x39, 0x76, - 0x4b, 0xb5, 0xbb, 0x2e, 0xb5, 0x14, 0x98, 0x94, - 0x14, 0xfd, 0xca, 0xaa, 0xa6, 0x5c, 0x1a, 0x85, - 0x9f, 0xab, 0x41, 0x76, 0x6f, 0x5b, 0xaf, 0xc5, - 0x4e, 0x7d, 0x2a, 0xe1, 0x19, 0x29, 0x85, 0x49, - 0x6c, 0x98, 0x46, 0x3a, 0xaf, 0x49, 0x0a, 0x91, - 0x64, 0xd6, 0x0d, 0x82, 0xf5, 0xf1, 0x8e, 0xbb, - 0x4c, 0x33, 0xde, 0xc5, 0x22, 0x89, 0x08, 0xd8, - 0x00, 0x72, 0x2d, 0x68, 0xd7, 0x4f, 0x7b, 0xc4, - 0x1a, 0xa1, 0xfb, 0xd5, 0x41, 0xe2, 0x3b, 0x6c, - 0x65, 0xeb, 0xb5, 0xbd, 0x14, 0xe8, 0x21, 0x07, - 0x71, 0xb5, 0x87, 0xd1, 0x6f, 0x5b, 0x22, 0x68, - 0x25, 0x84, 0xac, 0xfd, 0x4f, 0x51, 0x8b, 0x33, - 0x9c, 0xcb, 0x05, 0x0d, 0x28, 0xfe, 0xb6, 0x57, - 0x25, 0xd0, 0xe8, 0x7f, 0x7f, 0x2e, 0x5a, 0x32, - 0x28, 0x40, 0x5d, 0x7d, 0x74, 0xb4, 0xcd, 0x22, - 0x5e, 0xd4, 0x31, 0x10, 0xf6, 0xf6, 0xd8, 0x44, - 0xe3, 0xbc, 0x85, 0xd4, 0xf7, 0x2c, 0x0d, 0x7b, - 0x88, 0xd0, 0x15, 0x5f, 0x0a, 0x8a, 0x29, 0x01, - 0x29, 0x27, 0x26, 0xf1, 0xa3, 0x0b, 0x53, 0x8f, - 0xed, 0xad, 0x5e, 0xec, 0xb5, 0x1a, 0x3c, 0x7e, - 0x14, 0xaa, 0x47, 0x11, 0xc9, 0x48, 0x32, 0xfe, - 0xa6, 0x58, 0xe1, 0x38, 0x76, 0x90, 0x32, 0x5a, - 0x5b, 0x13, 0x2d, 0x34, 0x14, 0x00, 0x3f, 0xcc, - 0xd7, 0xe8, 0x48, 0x13, 0xe6, 0xfe, 0x8c, 0xd1, - 0x33, 0xfe, 0xf8, 0xa6, 0x75, 0xff, 0x2c, 0xb7, - 0xfc, 0x18, 0x4c, 0x7c, 0x39, 0x48, 0x88, 0xb1, - 0x35, 0x06, 0xfa, 0xad, 0x88, 0xd9, 0xae, 0x42, - 0x1b, 0x0b, 0x54, 0x95, 0x44, 0x5d, 0x39, 0xb6, - 0xda, 0xe5, 0x2d, 0xeb, 0x1b, 0xca, 0x8f, 0xab, - 0xd0, 0xb3, 0x7c, 0xdb, 0x5b, 0x00, 0x92, 0xfb, - 0x27, 0x26, 0x46, 0x84, 0xe9, 0xfe, 0x64, 0x0e, - 0x80, 0x07, 0x48, 0xf6, 0x44, 0x2f, 0xad, 0x94, - 0x54, 0xa0, 0x91, 0x96, 0xc8, 0xf6, 0x55, 0xbd, - 0xd5, 0x59, 0xe0, 0xf3, 0xae, 0x2a, 0xee, 0xd6, - 0x12, 0xec, 0xd7, 0x90, 0x0f, 0x5f, 0x7c, 0x34, - 0x31, 0xdb, 0x42, 0x4d, 0xe4, 0x82, 0x6d, 0xe5, - }; - - memset(key, 0x44, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - memset(plaintext, 0xAA, SZ); - - /* Test that all the end results are the same - no matter how many bytes we encrypt each call - */ - - //for (int bytes_to_process = 1; bytes_to_process < SZ; bytes_to_process++) { - int bytes_to_process = 17; - size_t offset = 0; - memset(iv, 0xEE, 16); - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = ( (idx + bytes_to_process) > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_aes_crypt_cfb128(&ctx, MBEDTLS_AES_ENCRYPT, length, &offset, iv, plaintext + idx, ciphertext + idx); - - } - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ); - - offset = 0; - memset(iv, 0xEE, 16); - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = ( (idx + bytes_to_process) > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_aes_crypt_cfb128(&ctx, MBEDTLS_AES_DECRYPT, length, &offset, iv, ciphertext + idx, decryptedtext + idx); - - } - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls CFB128 stream test", "[aes]") -{ - aes_cfb128_stream_test(TEST_AES_CFB128_DMA_MODE_LEN); -} - -/* Cipher produced via this Python: - import os, binascii - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - from cryptography.hazmat.backends import default_backend - key = b'\x44' * 16 - nonce = b'\xee' * 16 - cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()) - encryptor = cipher.encryptor() - ct = encryptor.update(b'\xaa' * 1000) + encryptor.finalize() - ct_arr = "" - for idx, b in enumerate(ct): - if idx % 8 == 0: - ct_arr += '\n' - ct_arr += "0x{}, ".format(format(b, '02x')) - print(ct_arr) -*/ - -/* Test the case where the input and output buffers point to the same location */ -TEST_CASE("mbedtls CTR, input buf = output buf", "[aes]") -{ - const unsigned SZ = 1000; - mbedtls_aes_context ctx; - uint8_t nonce[16]; - uint8_t stream_block[16]; - size_t nc_off = 0; - - const uint8_t expected_cipher_end[] = { - 0xd4, 0xdc, 0x4f, 0x8f, 0xfe, 0x86, 0xee, 0xb5, - 0x14, 0x7f, 0xba, 0x30, 0x25, 0xa6, 0x7f, 0x6c, - 0xb5, 0x73, 0xaf, 0x90, 0xd7, 0xff, 0x36, 0xba, - 0x2b, 0x1d, 0xec, 0xb9, 0x38, 0xfa, 0x0d, 0xeb, - }; - - memcpy(nonce, iv, 16); - - // allocate internal memory - uint8_t *buf = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(buf); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); - - memset(buf, 0x3A, SZ); - - // Encrypt - mbedtls_aes_crypt_ctr(&ctx, SZ, &nc_off, nonce, stream_block, buf, buf); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, buf + SZ - 32, 32); - - // Decrypt - nc_off = 0; - memcpy(nonce, iv, 16); - mbedtls_aes_crypt_ctr(&ctx, SZ, &nc_off, nonce, stream_block, buf, buf); - - for (int i = 0; i < SZ; i++) { - TEST_ASSERT_EQUAL_HEX8(0x3A, buf[i]); - } - - mbedtls_aes_free(&ctx); - free(buf); -} - -TEST_CASE("mbedtls OFB, chained DMA descriptors", "[aes]") -{ - // Max bytes in a single DMA descriptor is 4095 - const unsigned SZ = 6000; - mbedtls_aes_context ctx; - uint8_t nonce[16]; - size_t nc_off = 0; - - const uint8_t expected_cipher_end[] = { - 0xfe, 0xfa, 0xc9, 0x26, 0xb5, 0xc9, 0xea, 0xb0, - 0xdd, 0x1e, 0xe7, 0x0e, 0xfa, 0x5b, 0x4b, 0x94, - 0xaa, 0x5f, 0x60, 0x1e, 0xb2, 0x19, 0x3c, 0x2e, - 0xf6, 0x73, 0x56, 0x9f, 0xa7, 0xd5, 0xb7, 0x21, - }; - - memcpy(nonce, iv, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *plaintext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); - - memset(plaintext, 0x3A, SZ); - memset(decryptedtext, 0x0, SZ); - - // Encrypt - mbedtls_aes_crypt_ofb(&ctx, SZ, &nc_off, nonce, plaintext, ciphertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32); - - - // Decrypt - nc_off = 0; - memcpy(nonce, iv, 16); - mbedtls_aes_crypt_ofb(&ctx, SZ, &nc_off, nonce, ciphertext, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - - - -const uint8_t expected_cipher_ctr_end[] = { - 0x93, 0xca, 0xe0, 0x44, 0x96, 0x6d, 0xcb, 0xb2, - 0xcf, 0x8a, 0x8d, 0x73, 0x8c, 0x6b, 0xfa, 0x4d, - 0xd6, 0xc4, 0x18, 0x49, 0xdd, 0xc6, 0xbf, 0xc2, - 0xb9, 0xf0, 0x09, 0x69, 0x45, 0x42, 0xc6, 0x05, -}; - - -void aes_ctr_alignment_test(uint32_t input_buf_caps, uint32_t output_buf_caps) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - uint8_t key[16]; - uint8_t stream_block[16]; - size_t SZ = 32*200; - size_t ALIGNMENT_SIZE_BYTES = 64; - memset(nonce, 0x2F, 16); - memset(key, 0x1E, 16); - - // allocate memory according the requested caps - uint8_t *ciphertext = heap_caps_malloc(SZ + ALIGNMENT_SIZE_BYTES, output_buf_caps); - uint8_t *plaintext = heap_caps_malloc(SZ + ALIGNMENT_SIZE_BYTES, input_buf_caps); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - memset(plaintext, 0x26, SZ + ALIGNMENT_SIZE_BYTES); - - size_t offset; - - /* Shift buffers and test for all different misalignments */ - for (int i = 0; i < ALIGNMENT_SIZE_BYTES; i++ ) { - // Encrypt with input buffer in external ram - offset = 0; - memset(nonce, 0x2F, 16); - mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, plaintext + i, ciphertext + i); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_ctr_end, ciphertext + i + SZ - 32, 32); - - // Decrypt - offset = 0; - memset(nonce, 0x2F, 16); - // Decrypt with input buffer in instruction memory, the crypto DMA can't access this - mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, ciphertext + i, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - - } - - mbedtls_aes_free(&ctx); - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls AES internal mem alignment tests", "[aes]") -{ - uint32_t internal_dma_caps = INTERNAL_DMA_CAPS; - aes_ctr_alignment_test(internal_dma_caps, internal_dma_caps); -} - - -#ifdef CONFIG_SPIRAM_USE_MALLOC - -void aes_psram_one_buf_ctr_test(void) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - uint8_t key[16]; - uint8_t stream_block[16]; - size_t SZ = 32*200; - size_t ALIGNMENT_SIZE_BYTES = 32; - memset(nonce, 0x2F, 16); - memset(key, 0x1E, 16); - - // allocate external memory - uint8_t *buf = heap_caps_malloc(SZ + ALIGNMENT_SIZE_BYTES, PSRAM_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(buf); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - memset(buf, 0x26, SZ + ALIGNMENT_SIZE_BYTES); - - size_t offset; - - /* Shift buffers and test for all different misalignments */ - for (int i = 0; i < ALIGNMENT_SIZE_BYTES; i++ ) { - // Encrypt with input buffer in external ram - offset = 0; - memset(buf, 0x26, SZ + ALIGNMENT_SIZE_BYTES); - memset(nonce, 0x2F, 16); - mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, buf + i, buf + i); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_ctr_end, buf + i + SZ - 32, 32); - - // Decrypt - offset = 0; - memset(nonce, 0x2F, 16); - // Decrypt with input buffer in instruction memory, the crypto DMA can't access this - mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, buf + i, buf); - - TEST_ASSERT_EACH_EQUAL_HEX8(0x26, buf + i, SZ - i); - - } - mbedtls_aes_free(&ctx); - free(buf); -} - - -const uint8_t long_input[] = { - 0xf7, 0xe6, 0x6b, 0x8d, 0x2e, 0xbf, 0x88, 0xd6, - 0xb0, 0x77, 0xdf, 0x72, 0xbf, 0xa8, 0x0, 0x55, - 0xd5, 0xd1, 0x49, 0xa3, 0x2c, 0xc, 0xfe, 0xdb, - 0x17, 0x37, 0xa4, 0x1d, 0x70, 0x6b, 0x99, 0xf5, - 0x9e, 0x6, 0xad, 0x6c, 0xe0, 0x3b, 0xfa, 0x50, - 0x28, 0xb2, 0x62, 0xf2, 0x99, 0x3a, 0xcc, 0xe4, - 0x86, 0x5f, 0x1, 0xf8, 0x69, 0xd7, 0xf5, 0xb2, - 0x8a, 0x5f, 0x5c, 0x38, 0x9f, 0x8a, 0xb8, 0x8c, - 0xea, 0x6, 0xe1, 0x68, 0xff, 0xaf, 0x5d, 0xd9, - 0x1f, 0xa5, 0x5c, 0x8c, 0x52, 0xa1, 0x5f, 0x45, - 0x55, 0xcb, 0x76, 0x59, 0x8f, 0xfe, 0x36, 0xd0, - 0x85, 0x1f, 0x8, 0x90, 0x6f, 0x62, 0xb1, 0x1a, - 0xde, 0x75, 0xab, 0x90, 0xb7, 0x75, 0xe9, 0xa0, - 0xa9, 0xb0, 0xac, 0x61, 0x5, 0x6d, 0x9a, 0xe3, - 0x3b, 0x43, 0x61, 0x13, 0x8c, 0x3a, 0xa0, 0xaa, - 0x91, 0xea, 0x3e, 0xe1, 0x87, 0x35, 0xff, 0x90, - 0xe2, 0x43, 0xa3, 0x70, 0x57, 0x65, 0x2d, 0xa2, - 0x65, 0xe6, 0xde, 0xb0, 0x52, 0x85, 0x5b, 0xb8, - 0x3, 0x8, 0x63, 0x8b, 0xa1, 0xc2, 0xe1, 0x35, - 0x2e, 0xba, 0xe0, 0x84, 0x56, 0x52, 0x5f, 0x12, - 0xd3, 0x22, 0x8d, 0xa5, 0xbb, 0xe1, 0xd3, 0xfc, - 0x18, 0x1c, 0x90, 0x3b, 0x79, 0xe, 0xab, 0x2d, - 0x5e, 0xb0, 0x7, 0xbb, 0x46, 0x73, 0x1d, 0x35, - 0xd9, 0xc5, 0xa7, 0x87, 0x80, 0xf7, 0xee, 0x29, - 0xb5, 0x17, 0xf3, 0xaf, 0x30, 0xe5, 0x19, 0x50, - 0xf9, 0x5d, 0x2b, 0xc3, 0xc0, 0xda, 0x8f, 0xca, - 0x3c, 0x4d, 0xd5, 0xd7, 0x6c, 0xd2, 0x36, 0xa4, - 0x22, 0x8, 0x66, 0x48, 0x31, 0xb4, 0x3d, 0xc2, - 0xf6, 0x6b, 0xce, 0xf0, 0x12, 0xe4, 0x38, 0x5c, - 0xd8, 0x71, 0xea, 0x30, 0x52, 0xdf, 0x34, 0x62, - 0xdc, 0xb4, 0x30, 0xe, 0x74, 0xc, 0x5, 0x14, - 0xf, 0x47, 0x25, 0x5, 0x72, 0xc9, 0x14, 0x7c, - 0x1f, 0x6e, 0xdb, 0x6f, 0x83, 0x6, 0xa0, 0xb2, - 0x7f, 0x29, 0xe6, 0xb6, 0xe3, 0x11, 0x23, 0x4b, - 0x68, 0x92, 0xa, 0x49, 0xb5, 0x9d, 0x5d, 0x39, - 0x90, 0xff, 0x9, 0xa0, 0xa, 0x69, 0x6b, 0x2, - 0x18, 0xfb, 0xca, 0x5a, 0x91, 0x1a, 0xd9, 0x19, - 0x6b, 0xd4, 0x92, 0xd3, 0xd9, 0x7, 0xce, 0xcb, - 0xc7, 0xf3, 0xa1, 0x33, 0xcd, 0xa9, 0xb1, 0x44, - 0x8c, 0x93, 0xcd, 0xac, 0xc1, 0x44, 0x12, 0x48, - 0x95, 0x3, 0xdf, 0xc, 0x2f, 0xfc, 0x34, 0x8d, - 0x3, 0xde, 0xc1, 0xed, 0xdc, 0xf0, 0xfa, 0xa5, - 0xb2, 0x62, 0xcd, 0xa2, 0xbf, 0xf7, 0x7e, 0x47, - 0xb6, 0xcc, 0xe4, 0xa6, 0x4e, 0x51, 0xc6, 0x34, - 0xee, 0x83, 0x21, 0xb7, 0xc2, 0xe3, 0x13, 0x92, - 0xfc, 0xc9, 0x6, 0x6b, 0x91, 0x76, 0x7b, 0x2e, - 0x1e, 0xa2, 0xe0, 0x17, 0xab, 0x10, 0xfa, 0xac, - 0xd1, 0x2, 0x33, 0xb0, 0xd3, 0x3d, 0xb9, 0xce, - 0xea, 0xe9, 0x93, 0x5c, 0x98, 0x14, 0x0, 0xc6, - 0x2c, 0xa6, 0xdb, 0x1f, 0xdc, 0x76, 0xfb, 0xeb, - 0x9d, 0x55, 0xa6, 0x5f, 0xd5, 0x8e, 0x13, 0x39, - 0x88, 0x58, 0xff, 0xe8, 0xb4, 0x98, 0x9e, 0x4b, - 0xe7, 0x46, 0xdc, 0x7a, 0x68, 0x5b, 0xa8, 0xc2, - 0xe5, 0xa9, 0x50, 0xe2, 0x8, 0x31, 0x6, 0x3e, - 0x8e, 0xaf, 0x80, 0x24, 0x4e, 0xbd, 0x73, 0x6d, - 0xd9, 0x4b, 0xb4, 0x3e, 0x84, 0x5e, 0x31, 0x8e, - 0xf7, 0xa8, 0x9b, 0x5e, 0x2c, 0xd5, 0xe9, 0x7c, - 0xca, 0xca, 0xfa, 0x8e, 0x87, 0xbf, 0xf5, 0xa3, - 0x2f, 0x73, 0x2f, 0xc0, 0x5f, 0x46, 0xf4, 0x2, - 0xfd, 0xd1, 0x23, 0x6f, 0xc2, 0xc1, 0xc0, 0x86, - 0x62, 0x43, 0xc3, 0x44, 0x3b, 0x2c, 0x3d, 0xc2, - 0xd5, 0xe0, 0x2, 0xae, 0x1, 0x5a, 0x9, 0x89, - 0x52, 0x34, 0xdf, 0xb1, 0x6c, 0x2b, 0x85, 0x77, - 0xa5, 0x83, 0xe3, 0xa5, 0x50, 0x13, 0x2f, 0xf3, - 0xa6, 0x83, 0x60, 0x33, 0xba, 0xd5, 0xd2, 0x96, - 0x8a, 0xcd, 0xee, 0xfa, 0x76, 0x2a, 0x63, 0xec, - 0x41, 0x3a, 0xf3, 0xe5, 0x9e, 0x1d, 0x5e, 0x46, - 0x8, 0xd7, 0xe2, 0x3a, 0x25, 0x6f, 0x37, 0x7e, - 0x0, 0x2d, 0x3d, 0x1b, 0x86, 0xf4, 0xbe, 0x0, - 0x3c, 0xda, 0x82, 0x4a, 0xa3, 0x8, 0x2a, 0x38, - 0x95, 0xe, 0x38, 0xf8, 0x18, 0x6c, 0x42, 0x6f, - 0x30, 0x19, 0x8e, 0x22, 0xf6, 0xb7, 0x18, 0xb7, - 0x93, 0xd, 0x54, 0x72, 0x4, 0x64, 0xc1, 0x19, - 0x76, 0x6e, 0xfc, 0x9e, 0xb0, 0x7c, 0x20, 0x37, - 0xb0, 0xcb, 0x82, 0x3a, 0x20, 0x1d, 0x12, 0x44, - 0xbf, 0x44, 0xc4, 0x4d, 0x33, 0x7e, 0x7b, 0xeb, - 0xd8, 0xb8, 0xa1, 0x75, 0x9e, 0x47, 0x99, 0x64, - 0x92, 0xd3, 0x21, 0x1d, 0x72, 0x63, 0xc7, 0xb3, - 0x3d, 0xfc, 0xb9, 0x4, 0x65, 0x18, 0x94, 0xcc, - 0x20, 0xfe, 0x6f, 0x66, 0x36, 0xba, 0x36, 0x2a, - 0x7, 0xf0, 0x5e, 0x8a, 0xf2, 0x7, 0x1e, 0x9e, - 0x47, 0x2a, 0xc3, 0x7d, 0x7a, 0x20, 0x3c, 0x30, - 0x6f, 0xbe, 0x43, 0x5e, 0x71, 0x6f, 0xd, 0xb8, - 0x3d, 0x1d, 0x3e, 0x18, 0x65, 0x62, 0x75, 0xe8, - 0x34, 0xfd, 0x72, 0xbb, 0xd9, 0x3f, 0xf0, 0xa2, - 0x55, 0xee, 0x91, 0x12, 0x88, 0xda, 0x7, 0x3d, - 0x44, 0x88, 0x70, 0x1f, 0xe0, 0xbe, 0x4b, 0x88, - 0xa8, 0x8e, 0x28, 0x7, 0x73, 0xfd, 0x3f, 0xff, - 0x3e, 0xb2, 0xb5, 0xdb, 0x18, 0x48, 0x9e, 0x73, - 0x6e, 0xd7, 0x24, 0xa9, 0x25, 0xdb, 0x4, 0xe0, - 0xe0, 0xf4, 0x45, 0xc0, 0x1b, 0x82, 0xdf, 0x4e, - 0x48, 0x60, 0x85, 0x9c, 0xd8, 0x90, 0x32, 0xca, - 0x4b, 0xf9, 0xb4, 0xb8, 0xe1, 0xfe, 0xd2, 0xe0, - 0xb2, 0xd6, 0xb8, 0x19, 0x38, 0x34, 0x17, 0x8d, - 0x5e, 0xdf, 0xf4, 0xf1, 0xac, 0x2c, 0x88, 0x7f, - 0x54, 0xbc, 0xf1, 0x39, 0xf2, 0xaf, 0x5a, 0xff, - 0xa7, 0x96, 0x0, 0xf0, 0x27, 0x79, 0x27, 0x2e, - 0x9c, 0xf1, 0x4b, 0xa3, 0xad, 0xdc, 0x8a, 0x2c, - 0x9, 0x4c, 0xd3, 0xcd, 0xd0, 0x2d, 0xb1, 0xec, - 0x4d, 0x68, 0x40, 0xb8, 0xc5, 0x5, 0xfa, 0xb2, - 0x61, 0xb8, 0x31, 0x5, 0xea, 0xb8, 0xa3, 0x34, - 0xa8, 0x8b, 0x3, 0x5b, 0x22, 0x93, 0xba, 0x91, - 0x33, 0x3f, 0x8b, 0x5e, 0xed, 0x86, 0x23, 0x95, - 0xbc, 0x9e, 0xdf, 0xa9, 0x8c, 0xca, 0xb9, 0x97, - 0x9b, 0xc5, 0xca, 0xf4, 0xff, 0x4d, 0x62, 0x52, - 0x1c, 0xd3, 0x4c, 0x42, 0xbf, 0x8a, 0x25, 0x47, - 0xc7, 0x9, 0x4e, 0xe0, 0xb1, 0x72, 0x7d, 0x2, - 0x8f, 0xca, 0x4f, 0x4, 0xc8, 0x74, 0x82, 0x8e, - 0x53, 0xfd, 0xa1, 0x37, 0xda, 0x29, 0x5c, 0xa3, - 0x83, 0xe9, 0xa8, 0xd8, 0x25, 0x27, 0xfe, 0xf7, - 0x41, 0xc4, 0xb0, 0xee, 0x1d, 0x89, 0x1c, 0xe7, - 0xef, 0x86, 0x68, 0xd8, 0x87, 0x4c, 0x4f, 0x49, - 0xeb, 0xbc, 0xb3, 0x81, 0xa7, 0xf4, 0xb4, 0x9b, - 0xc1, 0x52, 0x93, 0x7e, 0xdf, 0x75, 0x75, 0xfc, - 0x45, 0xb2, 0x86, 0xa9, 0x50, 0xb5, 0xa3, 0xf7, - 0x61, 0x60, 0xe4, 0x13, 0x99, 0xc0, 0xf8, 0x49, - 0x7b, 0x61, 0x8b, 0xa8, 0xfa, 0x77, 0x0, 0xe4, - 0x6, 0x9a, 0xc5, 0x51, 0xe4, 0xeb, 0xaf, 0x5f, - 0xb9, 0x5c, 0x74, 0xc8, 0xf8, 0x3e, 0x62, 0x26, - 0xe, 0xe5, 0x85, 0xca, 0x49, 0xa0, 0x2f, 0xf7, - 0x7, 0x99, 0x3e, 0x5c, 0xe0, 0x72, 0xfa, 0xd4, - 0x80, 0x2e, 0xd6, 0x40, 0x6, 0xde, 0x5f, 0xc5, - 0xc5, 0x1, 0xd, 0xbf, 0xdb, 0xb6, 0xb3, 0x92, - 0x76, 0xb3, 0x3f, 0x3d, 0x5d, 0x1, 0x23, 0xb8, - 0xa, 0xcb, 0x80, 0x17, 0x31, 0x19, 0xc7, 0x64, - 0x69, 0xf1, 0x99, 0x53, 0xe5, 0xf2, 0x9f, 0x9d, - 0x3c, 0xda, 0xcb, 0xa6, 0x94, 0x94, 0x44, 0xd3, - 0xc6, 0x8b, 0xb5, 0xae, 0x45, 0x25, 0xef, 0x2a, - 0x24, 0x1, 0x3a, 0xf6, 0xf, 0xe, 0xcb, 0x10, - 0xc4, 0xe0, 0xf4, 0x3d, 0xf4, 0xf5, 0xea, 0x9b, - 0xd1, 0x16, 0x1b, 0x62, 0x11, 0x3e, 0x20, 0x3a, - 0x68, 0xc8, 0xf0, 0xe, 0x55, 0xbe, 0x51, 0x4d, - 0xbe, 0x1f, 0x4f, 0xda, 0x84, 0xda, 0xc4, 0x9e, - 0x24, 0xd7, 0x46, 0x82, 0x56, 0x4e, 0x61, 0x63, - 0xda, 0x18, 0xea, 0xc6, 0xc3, 0x21, 0x89, 0x18, - 0xe, 0x87, 0xb7, 0x91, 0xfe, 0x8d, 0xe, 0xac, - 0x75, 0x58, 0xe5, 0x9f, 0x1f, 0x93, 0xa6, 0x49, - 0x24, 0xa2, 0xc6, 0xe8, 0x9d, 0x9c, 0x6d, 0xc1, - 0xf, 0xfc, 0xe3, 0x57, 0xd3, 0xc2, 0x10, 0x91, - 0x9a, 0xa8, 0xaa, 0xd7, 0xf, 0xaa, 0x75, 0x90, - 0x4a, 0x10, 0xef, 0xb6, 0xdd, 0x6c, 0xd5, 0x1a, - 0xe3, 0xbb, 0xe0, 0x64, 0x44, 0xc, 0x59, 0xa1, - 0xef, 0x3, 0x52, 0xac, 0xa4, 0x85, 0x3e, 0x40, - 0xee, 0x5c, 0xef, 0xcf, 0xb1, 0xaa, 0x88, 0xe5, - 0x56, 0xb8, 0xcd, 0x87, 0xc7, 0xc6, 0xd3, 0xb4, - 0x85, 0x8f, 0x2a, 0xc9, 0xcd, 0x8a, 0x8b, 0x25, - 0x12, 0x71, 0x76, 0xc9, 0xaa, 0x62, 0x75, 0x80, - 0x6e, 0xa3, 0xf9, 0xa5, 0xfc, 0x90, 0xac, 0x28, - 0x13, 0x82, 0xbb, 0x5d, 0xa6, 0x93, 0x47, 0xd4, - 0xf, 0x3b, 0x19, 0xf6, 0x81, 0xdb, 0x55, 0xb0, - 0x47, 0x75, 0x63, 0x93, 0xb4, 0xdd, 0xf0, 0xaf, - 0xb7, 0x44, 0xcb, 0x7, 0x7b, 0x35, 0xc5, 0xe4, - 0x45, 0xfe, 0xbb, 0x11, 0x1a, 0x90, 0x96, 0x3a, - 0x7, 0x2a, 0xef, 0x9c, 0xc, 0xae, 0x38, 0x26, - 0xef, 0xc2, 0xc3, 0x53, 0xfa, 0x54, 0xcf, 0x6f, - 0xf7, 0xa, 0xea, 0x19, 0xa8, 0xf, 0xbd, 0xa7, - 0x3f, 0xcd, 0x38, 0x2c, 0xf3, 0x97, 0xfb, 0xdb, - 0xcb, 0xc5, 0x83, 0x80, 0x91, 0x3d, 0xc7, 0x29, - 0x67, 0x16, 0xa5, 0xd1, 0x41, 0xd0, 0xa1, 0x9b, - 0xde, 0x13, 0x83, 0x12, 0x36, 0x75, 0x81, 0x71, - 0x6b, 0xbc, 0x72, 0xcb, 0x37, 0x4, 0x6, 0x7c, - 0x3a, 0x22, 0x2b, 0xa, 0x11, 0xd3, 0x33, 0x8f, - 0x3, 0x54, 0x8e, 0x79, 0xb6, 0x36, 0x93, 0x92, - 0xb8, 0xf, 0x24, 0x4a, 0xd3, 0xd5, 0x27, 0x66, - 0xd1, 0xde, 0xe3, 0xaa, 0x4b, 0x2a, 0xe9, 0x22, - 0x9b, 0xbf, 0x6e, 0x9a, 0xf7, 0xa, 0x2f, 0x24, - 0x13, 0xd5, 0xd5, 0xbb, 0xa3, 0xba, 0x8f, 0xfc, - 0x28, 0xa8, 0xbe, 0xe6, 0x9f, 0xea, 0xed, 0xb1, - 0xba, 0xaf, 0xf, 0x1c, 0x1e, 0x51, 0xf8, 0xd7, - 0x1b, 0xa5, 0xa6, 0x63, 0x40, 0x6e, 0x3f, 0xa2, - 0x57, 0x6f, 0x57, 0xe4, 0x27, 0xc2, 0x3c, 0x33, - 0xc6, 0x9c, 0x24, 0xd0, 0x53, 0xc4, 0xfc, 0xed, - 0x8e, 0x1d, 0xf, 0xc3, 0x86, 0x9, 0x3d, 0x1d, - 0xc2, 0xdb, 0x24, 0x1a, 0x65, 0xf4, 0x30, 0xa5, - 0xc, 0x48, 0x37, 0xc5, 0x53, 0x35, 0x3b, 0xab, - 0xd, 0x96, 0x30, 0xd7, 0x1d, 0x66, 0x18, 0xc2, - 0x47, 0x3a, 0xef, 0xbe, 0x2e, 0xe4, 0x54, 0x9d, - 0xc4, 0xa5, 0xb9, 0xb3, 0x4c, 0x12, 0x73, 0x35, - 0xf0, 0x7, 0xe, 0x36, 0x88, 0xb2, 0x4b, 0x29, - 0xb, 0x4e, 0x84, 0x11, 0xaa, 0x9a, 0x3e, 0xb1, - 0xd7, 0xec, 0xfb, 0x7f, 0x10, 0x70, 0x1f, 0x26, - 0xf0, 0x27, 0x46, 0x5d, 0x4, 0x51, 0x97, 0x29, - 0xb4, 0x66, 0x39, 0x1, 0x82, 0x47, 0xd8, 0x5f, - 0xa9, 0xb3, 0xa1, 0xb8, 0xde, 0x1, 0xe1, 0xc4, - 0x47, 0xc5, 0xe8, 0xe6, 0xbb, 0xc0, 0xb6, 0x41, - 0x55, 0x10, 0x79, 0xa8, 0xd0, 0xd, 0x1, 0x56, - 0x29, 0x6c, 0xa5, 0x96, 0x87, 0x59, 0x4b, 0xd, - 0xc8, 0x3, 0x5, 0xaa, 0xa9, 0x6a, 0xb1, 0x10, - 0xbc, 0x1, 0x68, 0xd3, 0xa5, 0x52, 0x41, 0xe1, - 0x1f, 0x53, 0x7, 0xc6, 0xad, 0xb8, 0xc4, 0xf0, - 0x28, 0xe9, 0x3, 0x3a, 0xee, 0xce, 0x2c, 0xe2, - 0xb0, 0xda, 0x78, 0x3d, 0x37, 0x7, 0x2d, 0x1f, - 0xf1, 0x47, 0x81, 0x4, 0x67, 0x6e, 0xd, 0xa1, - 0x2b, 0x4, 0xe8, 0xd9, 0xf4, 0xaf, 0x35, 0xca, - 0xa5, 0xd1, 0xe3, 0xec, 0xc5, 0x82, 0x50, 0x99, - 0x9a, 0xee, 0xea, 0x53, 0x41, 0x86, 0x97, 0x44, - 0xeb, 0x58, 0x43, 0x47, 0xe7, 0xa0, 0xd3, 0x28, - 0xfc, 0xe7, 0x13, 0x8b, 0x56, 0xe3, 0xdb, 0xa9, - 0xcd, 0x9, 0xc8, 0x7, 0x11, 0xeb, 0xbf, 0xac, - 0x76, 0x72, 0x60, 0xaf, 0x9c, 0xba, 0x8a, 0x64, - 0xfb, 0xf4, 0xab, 0x27, 0x29, 0xe7, 0xec, 0x69, - 0x21, 0xcb, 0x5b, 0x79, 0x56, 0x10, 0xc1, 0x8, - 0xd5, 0x5d, 0x93, 0xb1, 0x70, 0x88, 0xf2, 0x19, - 0x41, 0xc6, 0xc2, 0x84, 0xdd, 0xf0, 0xb3, 0x40, - 0x12, 0x71, 0x24, 0x54, 0xc4, 0x5e, 0xfb, 0x5f, - 0x47, 0x8c, 0xa9, 0x4, 0x5a, 0xd5, 0x61, 0x19, - 0xb5, 0x7f, 0xc9, 0xbd, 0x87, 0xb2, 0xcd, 0x57, - 0x99, 0x50, 0x67, 0x1d, 0xb0, 0x1d, 0x82, 0xdd, - 0xef, 0x32, 0x38, 0xb9, 0xc7, 0x86, 0xb4, 0xd2, - 0xd6, 0xe1, 0x33, 0xb2, 0xdb, 0x5e, 0xc2, 0xa3, - 0x49, 0xa6, 0x5f, 0x79, 0x32, 0x50, 0x41, 0x5b, - 0xd7, 0x87, 0x74, 0xf5, 0xc9, 0x9c, 0x78, 0xb7, - 0xb, 0x1f, 0x72, 0xba, 0xd9, 0x3a, 0x4d, 0x18, - 0x45, 0x1d, 0xad, 0xef, 0xc4, 0xdc, 0x30, 0xe8, - 0x2, 0xb1, 0x7f, 0x6c, 0x8f, 0xaa, 0xd0, 0x40, - 0x17, 0xe, 0x58, 0x93, 0x42, 0x49, 0x63, 0x77, - 0x48, 0x55, 0x90, 0x2f, 0x7c, 0x3b, 0xee, 0x3c, - 0xac, 0xd, 0xd8, 0x72, 0x23, 0xd7, 0xa5, 0x6e, - 0xb0, 0xd2, 0x91, 0x25, 0x60, 0x9a, 0x52, 0xab, - 0xbd, 0x63, 0xce, 0xba, 0xda, 0xb1, 0xd7, 0xc7, - 0x3d, 0x21, 0x4e, 0x9c, 0x5a, 0x1e, 0x8d, 0xf4, - 0xa, 0xdb, 0xd9, 0xf, 0x20, 0x7e, 0xfb, 0xbf, - 0x36, 0x9c, 0x4f, 0xbd, 0xf7, 0xdb, 0x5b, 0xa2, - 0x6, 0xb2, 0x0, 0xe2, 0xa2, 0x9e, 0x4e, 0x19, - 0xd4, 0x69, 0xa9, 0x51, 0x69, 0x8b, 0xf5, 0xe1, - 0xad, 0x89, 0x8, 0xc5, 0x4f, 0xac, 0x1b, 0x7d, - 0xe7, 0xa, 0x9, 0x7d, 0x34, 0xf5, 0x3f, 0x46, - 0x80, 0xb9, 0xb9, 0x45, 0x58, 0xcd, 0x6c, 0xb5, - 0x5f, 0x60, 0xeb, 0x5a, 0xe3, 0xa3, 0x8, 0x5e, - 0xb1, 0xc4, 0x73, 0xc5, 0xa5, 0x67, 0x56, 0xd3, - 0xc6, 0x8a, 0x55, 0x6b, 0xd7, 0xd7, 0xc, 0x20, - 0xe6, 0xc, 0x73, 0x8, 0x2, 0x4b, 0xfb, 0xdd, - 0x4d, 0x4e, 0xa8, 0xb8, 0xd8, 0x4b, 0x53, 0x2f, - 0xc2, 0xfb, 0x5d, 0xa1, 0x6a, 0x16, 0x6b, 0xe, - 0xf1, 0xa1, 0xa5, 0x5b, 0xdf, 0x9c, 0x23, 0xb5, - 0x94, 0x9c, 0xae, 0x7b, 0xbe, 0x42, 0xb5, 0x79, - 0x80, 0xc3, 0x43, 0x41, 0xa4, 0x1b, 0x18, 0xfc, - 0x52, 0xcf, 0x43, 0xc5, 0x80, 0x7b, 0xbd, 0xc1, - 0x20, 0x5e, 0x65, 0xec, 0xc5, 0xfc, 0x3, 0xec, - 0x8f, 0x61, 0x66, 0xf5, 0x15, 0x67, 0xc8, 0xb6, - 0xef, 0x9a, 0xba, 0xb7, 0xcb, 0x2c, 0xac, 0x1b, - 0x50, 0xda, 0xb6, 0x29, 0xa4, 0x37, 0xe9, 0x96, - 0xa0, 0x7, 0x7d, 0x49, 0xa6, 0xce, 0xf3, 0xf0, - 0x19, 0xdf, 0x61, 0xc7, 0xa4, 0x7b, 0x5a, 0xd4, - 0x99, 0xb2, 0x64, 0xe7, 0xd1, 0x6b, 0x7f, 0xe8, - 0xb8, 0xd3, 0x89, 0xee, 0x96, 0xc0, 0xed, 0x5d, - 0x7e, 0x48, 0x2, 0xd2, 0x25, 0xd0, 0x5, 0xef, - 0x93, 0x72, 0x7c, 0x8c, 0xbd, 0x6e, 0x49, 0xd3, - 0x38, 0x46, 0x1c, 0xff, 0x28, 0x4e, 0x1b, 0xad, - 0x39, 0x2f, 0x65, 0x26, 0xe2, 0x70, 0x3d, 0xb8, - 0x7a, 0xd3, 0x38, 0x38, 0xfc, 0x3a, 0x67, 0x78, - 0xdb, 0x9, 0xcb, 0xbf, 0xc9, 0xe1, 0xee, 0x69, - 0x2b, 0xd, 0xb1, 0x79, 0x13, 0xd0, 0xa5, 0x75, - 0x6, 0x8, 0x79, 0xa7, 0x7c, 0xc, 0xe7, 0x1b, - 0x9c, 0x36, 0x64, 0xbe, 0x20, 0x65, 0xa2, 0xd4, - 0xd9, 0xc, 0x68, 0xe, 0x88, 0x2b, 0x93, 0x60, - 0xf1, 0xa5, 0x82, 0xc5, 0x4d, 0x2b, 0x7d, 0x73, - 0xe9, 0x13, 0x8c, 0xc1, 0x8, 0xbd, 0x21, 0x65, - 0x77, 0x2f, 0x34, 0xb1, 0x97, 0x9f, 0xd8, 0x55, - 0xcf, 0x75, 0xc2, 0xf2, 0x41, 0x68, 0xc1, 0x9c, - 0x1c, 0xd7, 0x23, 0xbf, 0x83, 0x2a, 0x9, 0x66, - 0xce, 0x8f, 0xd2, 0x12, 0x79, 0x93, 0xef, 0x8, - 0x9b, 0xeb, 0x2f, 0xc, 0xe4, 0x5b, 0x71, 0x1a, - 0xef, 0x11, 0x65, 0xd8, 0x6d, 0x8c, 0x59, 0x53, - 0x70, 0x1d, 0xb5, 0x81, 0xff, 0xc0, 0x7d, 0x87, - 0xa5, 0x21, 0x5d, 0x9f, 0x63, 0xb2, 0xe7, 0xe9, - 0xd0, 0x49, 0x41, 0xc7, 0x3c, 0xe1, 0x2b, 0xb1, - 0xac, 0x15, 0xcd, 0xb0, 0xa8, 0xdc, 0xae, 0x3b, - 0xef, 0x32, 0x98, 0x8c, 0xc7, 0x40, 0xa6, 0x81, - 0x1, 0xa1, 0x7d, 0x89, 0x46, 0x99, 0x91, 0x24, - 0xce, 0xb2, 0x70, 0x82, 0x92, 0xf3, 0x60, 0x66, - 0x34, 0x6, 0x37, 0xad, 0x5c, 0xed, 0xc3, 0x27, - 0x68, 0x8c, 0x56, 0xe7, 0xf, 0x73, 0x5c, 0x7e, - 0x9e, 0xd0, 0x8c, 0x99, 0x5a, 0xb1, 0x15, 0x98, - 0xbb, 0x79, 0x9f, 0xd1, 0x69, 0xce, 0x76, 0x5, - 0xcb, 0x8e, 0x18, 0xb3, 0x84, 0x65, 0xa9, 0x2, - 0xbc, 0x43, 0x8b, 0x7e, 0xe9, 0xe2, 0xe6, 0x74, - 0x31, 0x8d, 0xe7, 0xa2, 0x42, 0x8f, 0xca, 0x38, - 0x59, 0x85, 0x25, 0x47, 0xd2, 0x86, 0x47, 0x9, - 0xc2, 0x11, 0x2, 0x91, 0xe6, 0xf3, 0x47, 0xc2, - 0x9c, 0x28, 0x2f, 0xbb, 0xac, 0xde, 0x9f, 0xd, - 0xc2, 0x96, 0x4f, 0x43, 0xca, 0x32, 0xed, 0x34, - 0xba, 0xad, 0xef, 0xbe, 0x68, 0xc7, 0xa2, 0x83, - 0xaf, 0xe, 0xd3, 0x72, 0x52, 0xd1, 0x76, 0x3d, - 0x9a, 0x98, 0x39, 0xf4, 0x3e, 0x14, 0x27, 0xff, - 0xb2, 0x37, 0x23, 0xc5, 0x6d, 0x66, 0xef, 0xaa, - 0xfe, 0xe7, 0xe4, 0x86, 0xa1, 0xe, 0x4e, 0x36, - 0x64, 0xb1, 0x67, 0xf, 0x94, 0x6f, 0x77, 0xd5, - 0xec, 0xe2, 0x5e, 0xc8, 0xe3, 0x64, 0x29, 0x92, - 0xd, 0x20, 0x34, 0x9f, 0x19, 0x6e, 0x85, 0xf8, - 0x48, 0x78, 0xb0, 0xf, 0x42, 0xb2, 0x8c, 0xea, - 0xc2, 0x4d, 0xd3, 0x23, 0xb, 0x4d, 0x20, 0x33, - 0xc7, 0x46, 0x0, 0x45, 0x37, 0xc6, 0xcb, 0xd0, - 0xec, 0x11, 0xc6, 0x74, 0x91, 0x7d, 0x6b, 0x54, - 0x56, 0x10, 0x8d, 0xd0, 0xce, 0xe8, 0x57, 0x3b, - 0x83, 0xd8, 0x25, 0x51, 0x79, 0x48, 0xa, 0xa5, - 0xc3, 0xe4, 0x65, 0x33, 0xb2, 0x89, 0xa6, 0x4c, - 0xe8, 0xc8, 0x9e, 0xce, 0xea, 0x2a, 0x55, 0x40, - 0xfc, 0x26, 0x29, 0xd4, 0x2d, 0x7e, 0xe1, 0xb1, - 0x4d, 0x65, 0x1, 0xe9, 0x98, 0xc9, 0xf4, 0x69, - 0x10, 0xd9, 0xa3, 0xf9, 0x34, 0xaf, 0x3c, 0x34, - 0x64, 0x23, 0xde, 0xb8, 0x1c, 0x33, 0x18, 0x74, - 0x67, 0xb4, 0x4a, 0x71, 0xa6, 0x89, 0x2, 0xfe, - 0xf7, 0xf1, 0x32, 0xc7, 0x98, 0xad, 0xe5, 0x10, - 0x98, 0x3c, 0x6c, 0xaf, 0x1f, 0x13, 0x3d, 0xcc, - 0xfc, 0x3b, 0x67, 0x33, 0x34, 0xc9, 0x31, 0xcd, - 0x3f, 0xd, 0x3c, 0x5a, 0xb6, 0xc2, 0x8, 0xea, - 0xe2, 0xae, 0xdd, 0xfc, 0x6f, 0xca, 0xb5, 0x67, - 0x11, 0xce, 0xd5, 0xda, 0x3a, 0x8b, 0x7, 0xf2, - 0xc0, 0x9e, 0x78, 0x18, 0x92, 0x9f, 0x64, 0x26, - 0x9f, 0x66, 0x62, 0x66, 0xa1, 0x7e, 0x3, 0xf5, - 0xb9, 0xe6, 0x74, 0x20, 0x88, 0xb7, 0x7e, 0x62, - 0x7a, 0x33, 0x21, 0x9, 0x9c, 0x91, 0x3b, 0x62, - 0x9, 0x46, 0xd3, 0xd1, 0x1f, 0xc5, 0x3a, 0x8f, - 0x69, 0x27, 0x2c, 0x7b, 0xec, 0xda, 0x79, 0xf1, - 0xc9, 0xe9, 0x98, 0xd0, 0xa, 0xc9, 0xf6, 0x37, - 0x28, 0xf8, 0xfc, 0xe, 0xdc, 0xf, 0xe9, 0x23, - 0xf6, 0x84, 0x25, 0x96, 0x2c, 0x24, 0x14, 0xd7, - 0xe2, 0x5e, 0x1c, 0x56, 0x7f, 0x99, 0x98, 0x62, - 0x76, 0xcc, 0x84, 0x44, 0xd6, 0xb9, 0x47, 0x2b, - 0x52, 0xfb, 0x42, 0x40, 0xf3, 0x63, 0xaf, 0xd4, - 0x10, 0x5, 0xf9, 0x3b, 0xc8, 0x53, 0xa9, 0x45, - 0xa4, 0x50, 0x41, 0x83, 0xe8, 0x4a, 0x9, 0xb6, - 0xf1, 0x77, 0x70, 0xe3, 0x61, 0x30, 0xd8, 0x90, - 0x49, 0x52, 0x4b, 0x4a, 0xf2, 0x66, 0x84, 0xaf, - 0x71, 0x1, 0x40, 0x66, 0xf6, 0x3, 0xc9, 0x23, - 0xb1, 0x1a, 0xc1, 0xb2, 0xf7, 0x35, 0x1a, 0xc9, - 0x3a, 0x75, 0xb1, 0xa7, 0x4, 0xff, 0x69, 0xa, - 0x90, 0x58, 0xd4, 0xf4, 0x16, 0x79, 0xe1, 0xae, - 0x39, 0x9d, 0xbb, 0x32, 0x6b, 0x3, 0xe2, 0xf5, - 0x73, 0x83, 0x7e, 0x3c, 0xf8, 0x29, 0xab, 0xcc, - 0xdc, 0xf0, 0x13, 0xdb, 0x86, 0x28, 0x88, 0x8e, - 0xde, 0x6a, 0x29, 0xf1, 0xea, 0x0, 0x83, 0x97, - 0x1, 0x32, 0x5f, 0xaa, 0x5b, 0x1b, 0xe4, 0x87, - 0xec, 0x90, 0x45, 0xc7, 0xc5, 0x6c, 0x11, 0x83, - 0x95, 0xab, 0xdd, 0x71, 0x69, 0x24, 0xc, 0x5c, - 0xc0, 0xf3, 0xc1, 0xb0, 0x5e, 0x1, 0x5e, 0x4, - 0xa1, 0x6e, 0x6e, 0x7d, 0x3f, 0x6f, 0xbd, 0x5d, - 0x9, 0x8f, 0x23, 0x53, 0x74, 0x4b, 0xa9, 0x53, - 0xd2, 0x10, 0xa1, 0xc0, 0x8e, 0x18, 0xa, 0x2f, - 0x88, 0x8d, 0x4b, 0xf8, 0xc2, 0x3d, 0xeb, 0x34, - 0x23, 0xa, 0x80, 0xc, 0x69, 0x21, 0x3, 0xc1, - 0x6f, 0xbe, 0xdf, 0xf6, 0x2c, 0x27, 0x77, 0xa2, - 0xc5, 0x5c, 0x9, 0x54, 0x5d, 0x4a, 0x4c, 0xb, - 0x6b, 0xb5, 0x88, 0x11, 0x42, 0x62, 0x39, 0x89, - 0x9e, 0x36, 0xd3, 0x91, 0xf6, 0x70, 0x18, 0x35, - 0x79, 0xaf, 0x73, 0xf3, 0x0, 0x75, 0x5a, 0xa3, - 0xce, 0xf1, 0x42, 0x80, 0x19, 0x5e, 0x42, 0x56, - 0x53, 0x85, 0xbb, 0xf4, 0x29, 0xac, 0x84, 0x1d, - 0x97, 0x1, 0x1c, 0xc4, 0x58, 0xcb, 0x33, 0xc4, - 0xdc, 0x1e, 0x59, 0x8f, 0x48, 0xa9, 0x59, 0xfd, - 0xaf, 0xa3, 0x5c, 0x19, 0x17, 0x6b, 0x46, 0x2d, - 0xab, 0x44, 0xa3, 0xcc, 0x1a, 0xaa, 0x23, 0x4e, - 0x58, 0x37, 0x7b, 0x11, 0x14, 0xc2, 0xf1, 0xc9, - 0x58, 0x99, 0xd3, 0x3c, 0xec, 0xb9, 0xbe, 0x17, - 0x3c, 0x8d, 0x1c, 0x87, 0x9d, 0xe1, 0xb9, 0xad, - 0x68, 0x36, 0xd5, 0xfc, 0x24, 0x9b, 0x34, 0x5, - 0x26, 0xac, 0x15, 0x9f, 0xd6, 0x70, 0x74, 0x6c, - 0x72, 0xf, 0x6, 0x6, 0x5a, 0xc, 0xc0, 0x78, - 0x47, 0x8e, 0xcf, 0xf2, 0xce, 0x8, 0xe2, 0xa4, - 0xc6, 0x7d, 0x2d, 0x70, 0x14, 0xe2, 0xc6, 0xfc, - 0x63, 0x7a, 0x42, 0x8c, 0x45, 0xae, 0xe8, 0x3b, - 0x30, 0x48, 0xda, 0x3e, 0x14, 0xb5, 0x8b, 0x10, - 0xae, 0x56, 0xbd, 0x17, 0xdf, 0xcb, 0x63, 0xf5, - 0xb, 0x2b, 0xd7, 0x34, 0x7c, 0x96, 0x43, 0xe9, - 0x17, 0xd4, 0x53, 0x2b, 0x4e, 0xba, 0x61, 0x57, - 0x92, 0xdb, 0xe8, 0x37, 0xf4, 0xa3, 0x59, 0x88, - 0x74, 0xc2, 0x3c, 0x5d, 0x54, 0x30, 0xb9, 0x6, - 0xbe, 0x75, 0x13, 0xe8, 0xf2, 0xe8, 0xcb, 0x45, - 0x73, 0x70, 0xaf, 0x94, 0xe6, 0xc5, 0xb0, 0xdf, - 0xd2, 0xd5, 0x57, 0x97, 0x7c, 0x97, 0xde, 0x55, - 0xaf, 0xbb, 0xed, 0x19, 0x35, 0x17, 0xf4, 0x23, - 0x38, 0x9c, 0xce, 0x37, 0xfe, 0xd8, 0x4e, 0xd8, - 0x99, 0xba, 0x33, 0x22, 0xf2, 0xeb, 0xab, 0x97, - 0xee, 0x9d, 0xab, 0x67, 0x95, 0x35, 0xdf, 0xc8, - 0xb6, 0xa0, 0xf, 0x15, 0x51, 0xa9, 0x76, 0x15, - 0xdd, 0xbd, 0xac, 0x12, 0xce, 0x51, 0xde, 0x68, - 0x15, 0xaf, 0x27, 0xcf, 0xd1, 0xba, 0x7c, 0x17, - 0xef, 0xbf, 0xbb, 0xc0, 0x6e, 0x58, 0x73, 0xf6, - 0x57, 0xe1, 0x8d, 0xb0, 0x9a, 0x5a, 0x9, 0x19, - 0xef, 0xdd, 0x4, 0xe1, 0x76, 0x94, 0x31, 0xd7, - 0x26, 0x9f, 0x9c, 0x27, 0xc4, 0x2b, 0x4b, 0xf6, - 0x3b, 0xa1, 0x8c, 0xf4, 0x21, 0xde, 0x39, 0x14, - 0x5a, 0x54, 0xac, 0x95, 0x2f, 0xa0, 0x60, 0x53, - 0x87, 0x5b, 0x71, 0x92, 0xae, 0xf9, 0x6c, 0x62, - 0x76, 0x7e, 0x91, 0x11, 0xa6, 0xf4, 0xf2, 0xa8, - 0xdf, 0xc1, 0xf6, 0x3a, 0xdb, 0x34, 0x96, 0x9, - 0x71, 0xb4, 0x4, 0xfa, 0xd4, 0x3, 0x46, 0x16, - 0x78, 0x41, 0x42, 0x7d, 0x15, 0x68, 0x63, 0x55, - 0x23, 0x4, 0x46, 0x5d, 0xe1, 0xd8, 0xe7, 0x5f, - 0x55, 0x39, 0xd2, 0x45, 0xb2, 0x0, 0x35, 0xde, - 0xd8, 0x9d, 0xc7, 0x3a, 0x8f, 0x37, 0x7e, 0xe5, - 0x9e, 0xcf, 0xd1, 0x6a, 0x22, 0xe1, 0x51, 0xb2, - 0xe6, 0x99, 0x3e, 0x83, 0xeb, 0x34, 0x9d, 0x34, - 0x7, 0x1c, 0xbe, 0x91, 0x69, 0x9e, 0xaa, 0xcb, - 0x86, 0xd2, 0xb6, 0xed, 0xa5, 0x4, 0xf9, 0x7d, - 0xf8, 0xba, 0x2a, 0x27, 0x38, 0xe1, 0xaa, 0x22, - 0x94, 0x46, 0x1f, 0x1b, 0xcf, 0xc4, 0x78, 0x88, - 0x3d, 0x50, 0x83, 0x30, 0x61, 0x87, 0xb6, 0x38, - 0x5b, 0x4f, 0x5a, 0x3, 0x2d, 0x5d, 0xa6, 0x33, - 0x38, 0xe7, 0x8b, 0x60, 0x1, 0x8e, 0xde, 0x69, - 0x8e, 0x4d, 0x60, 0x24, 0x3b, 0x47, 0x4b, 0x56, - 0xea, 0xf9, 0xc8, 0xfa, 0x2d, 0x65, 0x7b, 0xad, - 0xee, 0xe4, 0x91, 0x20, 0x6f, 0x64, 0x6e, 0x81, - 0x69, 0xda, 0xf5, 0x3c, 0x3d, 0xff, 0x4c, 0xe9, - 0x9b, 0x4d, 0xa8, 0x67, 0x9e, 0x67, 0x7f, 0x84, - 0xdb, 0x7a, 0xb7, 0x24, 0x32, 0xa0, 0x80, 0x16, - 0x55, 0x2d, 0x1d, 0xc1, 0x3a, 0x19, 0xd3, 0x17, - 0x74, 0x8e, 0x2a, 0x5c, 0xf6, 0x71, 0xf7, 0x25, - 0x3a, 0x54, 0x28, 0xef, 0x50, 0x78, 0x14, 0x5, - 0x49, 0x8a, 0xbb, 0x71, 0xb2, 0xed, 0xa2, 0x5b, - 0xff, 0x2, 0xe, 0xd8, 0x1a, 0x8b, 0x3c, 0xcc, - 0x58, 0x27, 0x71, 0x2d, 0xb, 0x11, 0x9f, 0x6, - 0xc3, 0xfd, 0x37, 0x19, 0xdb, 0xec, 0xa5, 0x4b, - 0x93, 0x81, 0xb6, 0xff, 0xd4, 0xf5, 0x7b, 0xf5, - 0x49, 0x5b, 0x95, 0x9, 0xa4, 0xca, 0xa5, 0x33, - 0x9a, 0xfc, 0x97, 0xec, 0x7b, 0xb, 0xb9, 0x2e, - 0x3b, 0x9d, 0x52, 0xc2, 0xa2, 0x9, 0xc8, 0xbf, - 0x39, 0x16, 0xce, 0x42, 0x3, 0x4b, 0xe3, 0xfc, - 0xfd, 0xc, 0x37, 0x96, 0x10, 0x36, 0xad, 0x44, - 0xda, 0xc5, 0x58, 0x3e, 0x78, 0x52, 0xa1, 0x65, - 0xed, 0x89, 0xe7, 0xea, 0xbf, 0xa8, 0x6a, 0xf2, - 0xa7, 0x8e, 0x9d, 0x1, 0x25, 0x83, 0x57, 0x5f, - 0x51, 0xe6, 0xe1, 0xa4, 0x4f, 0xf6, 0x81, 0xd7, - 0xe6, 0x98, 0x29, 0x98, 0x58, 0xfe, 0xda, 0x45, - 0xab, 0x38, 0x6, 0x91, 0x97, 0xb7, 0xa3, 0x4f, - 0x93, 0x8d, 0x8a, 0x8b, 0x5, 0xe9, 0x5, 0x98, - 0x3b, 0xc4, 0xb7, 0xe1, 0x68, 0x58, 0xa0, 0x3b, - 0x99, 0xea, 0x8a, 0xa9, 0xfb, 0x55, 0xe2, 0xc7, - 0x1d, 0x87, 0x3, 0x40, 0x24, 0x13, 0x28, 0x6a, - 0x34, 0x8a, 0xff, 0x62, 0x91, 0xb8, 0x7d, 0x28, - 0x1a, 0xd2, 0xfc, 0x4e, 0xa3, 0xda, 0x66, 0x69, - 0x15, 0xc0, 0xda, 0x15, 0x3e, 0x67, 0x12, 0x95, - 0x6, 0x1b, 0xf4, 0x60, 0xe4, 0x39, 0x82, 0xe9, - 0x2e, 0xbe, 0xab, 0x8c, 0x2c, 0x6e, 0xd6, 0x40, - 0x91, 0xc0, 0x68, 0xf7, 0xa2, 0x41, 0xd0, 0xa8, - 0x7, 0xab, 0x13, 0x34, 0x16, 0xf4, 0x73, 0x4f, - 0x1d, 0x21, 0x1a, 0x7d, 0xad, 0x43, 0x12, 0xf, - 0xb7, 0xfe, 0xa3, 0x81, 0xe9, 0xb5, 0x2d, 0xd3, - 0xa, 0x29, 0xb5, 0x32, 0xcb, 0x49, 0x6f, 0x1, - 0x90, 0x45, 0x62, 0xca, 0x1b, 0x66, 0x39, 0x88, - 0x1c, 0xee, 0x30, 0xa8, 0xb5, 0x37, 0xd0, 0xfa, - 0x46, 0x52, 0x16, 0x30, 0x17, 0xcf, 0x88, 0xd0, - 0x4, 0x5d, 0xde, 0x5e, 0x4f, 0xe7, 0xa9, 0xbf, - 0x3c, 0x29, 0x3a, 0x63, 0x67, 0x23, 0xb3, 0x7c, - 0x51, 0x17, 0xfe, 0x8d, 0xdb, 0xc8, 0x8d, 0x70, - 0xe9, 0x6f, 0x56, 0xe5, 0x44, 0xb2, 0x94, 0xeb, - 0x47, 0xca, 0x3a, 0xdc, 0xe3, 0x33, 0x87, 0x9c, - 0xe8, 0x89, 0x4b, 0x41, 0xb8, 0xb3, 0x69, 0xb0, - 0x7f, 0xc8, 0xc7, 0x74, 0xf5, 0xcb, 0x20, 0xad, - 0xea, 0xbb, 0x3d, 0x11, 0xc6, 0xc0, 0xd2, 0x88, - 0x8b, 0x16, 0xee, 0x62, 0x5a, 0x4d, 0x32, 0xe7, - 0x48, 0xae, 0xab, 0x5e, 0xc2, 0x83, 0xc4, 0xfc, - 0xd1, 0xb9, 0x71, 0xf2, 0x9, 0x7f, 0xdc, 0xbc, - 0x28, 0x74, 0xa0, 0x37, 0xa9, 0x5b, 0x6c, 0x7c, - 0x9b, 0x61, 0x94, 0x88, 0xf7, 0x40, 0x84, 0x75, - 0xa5, 0x50, 0xab, 0xb0, 0x92, 0x66, 0x10, 0x66, - 0xf6, 0xec, 0x6b, 0x5e, 0x31, 0x9b, 0xc4, 0xfa, - 0x95, 0x8b, 0xe7, 0xd4, 0xba, 0x81, 0xd2, 0x85, - 0x30, 0x4, 0x8b, 0x3d, 0xfa, 0x8a, 0x8f, 0x9b, - 0x54, 0x6a, 0x4d, 0x35, 0xa2, 0xe9, 0x58, 0x95, - 0xe3, 0xd1, 0x71, 0xcd, 0x3a, 0x54, 0xae, 0xd9, - 0x5c, 0x83, 0xd, 0x15, 0x64, 0x66, 0xee, 0x39, - 0xa1, 0x85, 0xe2, 0x28, 0xf5, 0x66, 0x5f, 0xec, - 0x39, 0x70, 0x96, 0x2c, 0x72, 0x9e, 0x57, 0xfd, - 0x57, 0x27, 0xb7, 0xda, 0x79, 0x39, 0xd8, 0x3b, - 0x2e, 0xa3, 0xb0, 0xde, 0xbf, 0x60, 0xb6, 0x42, - 0x78, 0x9d, 0x8f, 0xe8, 0x1c, 0x7c, 0x45, 0x72, - 0x3, 0xc4, 0xd5, 0x81, 0xf6, 0xe6, 0x9, 0x29, - 0x1e, 0xcd, 0xf3, 0xe, 0xd6, 0x65, 0xee, 0x6d, - 0x90, 0x17, 0x95, 0x20, 0x54, 0xf1, 0xd, 0x2f, - 0xa0, 0xac, 0xe3, 0x4b, 0xfc, 0xa4, 0xdc, 0xab, - 0x9d, 0x9e, 0x32, 0x63, 0x72, 0xd1, 0xb4, 0xef, - 0xf1, 0x83, 0xa7, 0xd7, 0x2b, 0x1a, 0x9a, 0x9e, - 0xfa, 0x1e, 0xb, 0x2b, 0xdc, 0x7b, 0x87, 0x96, - 0xf, 0xdb, 0x75, 0xb9, 0x6, 0x2b, 0xd3, 0x95, - 0xc5, 0xb3, 0x9, 0x53, 0x94, 0x54, 0x1f, 0xd0, - 0x75, 0x5a, 0x36, 0x6a, 0x7c, 0x82, 0xdb, 0xb1, - 0xa2, 0x17, 0xbc, 0xeb, 0x1f, 0xfa, 0x34, 0x3d, - 0xee, 0x68, 0xee, 0x93, 0x33, 0xfb, 0xcb, 0xd2, - 0xa3, 0xd1, 0x24, 0x5e, 0xf4, 0x9, 0xbe, 0x5a, - 0x68, 0x9e, 0x3e, 0xd4, 0x81, 0xcd, 0xa3, 0x1e, - 0x2, 0x13, 0xb4, 0x79, 0x94, 0xc9, 0xb2, 0xde, - 0x56, 0xf1, 0x7b, 0x2f, 0xe2, 0x56, 0xe1, 0x10, - 0xf4, 0x73, 0x2d, 0xc9, 0xca, 0x4d, 0x5f, 0x11, - 0x9e, 0xd6, 0x3c, 0x73, 0x12, 0x57, 0xe9, 0x14, - 0xe0, 0x8d, 0xdd, 0x4b, 0x8a, 0xbb, 0xb3, 0x78, - 0xbe, 0x16, 0x94, 0x93, 0x51, 0x33, 0x7a, 0xa5, - 0x41, 0x14, 0x60, 0x82, 0x94, 0x67, 0x70, 0xea, - 0xe6, 0x3, 0x7f, 0xc5, 0xa0, 0x20, 0x15, 0x88, - 0x53, 0xe3, 0x7e, 0x16, 0x52, 0xe4, 0xca, 0xa0, - 0x6f, 0xb9, 0x68, 0x4e, 0x30, 0xb9, 0x8c, 0xe6, - 0x9c, 0x5e, 0xc2, 0x93, 0xf9, 0xe1, 0x41, 0x4b, - 0x18, 0x42, 0x6f, 0x8f, 0x96, 0x3d, 0x2b, 0x28, - 0xd5, 0x53, 0x62, 0xdd, 0x6b, 0xd0, 0xf8, 0x2e, - 0xa6, 0x97, 0xe5, 0x87, 0xc5, 0xf6, 0x96, 0x7b, - 0xc4, 0x3e, 0x84, 0xc9, 0xf6, 0x34, 0x63, 0x46, - 0xe1, 0x10, 0xa5, 0x91, 0x6b, 0xff, 0x10, 0x3f, - 0x50, 0x2e, 0xd7, 0x39, 0x12, 0x7a, 0x15, 0x85, - 0xed, 0x99, 0xdb, 0x9b, 0x99, 0x6b, 0xfa, 0xfa, - 0x93, 0x7, 0x44, 0xbe, 0xbe, 0x60, 0x23, 0xc1, - 0xec, 0x5c, 0xf6, 0x93, 0x38, 0xf9, 0x89, 0x0, - 0xc5, 0x5f, 0x5b, 0xe2, 0x9d, 0x2b, 0xea, 0x6b, - 0x2e, 0xee, 0xb7, 0x4a, 0x4e, 0x8d, 0xd0, 0x35, - 0xe9, 0xc1, 0x5, 0x2b, 0x83, 0xb7, 0x72, 0x25, - 0xbb, 0xbe, 0xe8, 0x15, 0xf4, 0x74, 0x69, 0x69, - 0x67, 0x8c, 0x5c, 0x31, 0x79, 0x78, 0x2e, 0x43, - 0x83, 0xd1, 0xdd, 0x9, 0xc3, 0xa1, 0x0, 0x13, - 0x31, 0x4b, 0x86, 0xce, 0xee, 0xd7, 0xec, 0xb1, - 0x2c, 0x38, 0x46, 0x68, 0x62, 0xd9, 0x84, 0xdb, - 0x24, 0x62, 0x82, 0xc, 0x12, 0xb7, 0x4f, 0x86, - 0x54, 0x18, 0xc6, 0xd7, 0x94, 0x8b, 0xf2, 0x4c, - 0x17, 0x98, 0xaa, 0xe0, -}; - -const uint8_t expected_cipher_long_input_end[] = { - 0x05, 0x95, 0x58, 0x7b, 0xb4, 0x60, 0x15, - 0x32, 0x9f, 0x38, 0xcc, 0x98, 0x1b, 0xbe, 0x10, 0xa5, 0x06, 0x67, 0xae, 0x38, - 0xbd, 0x7d, 0xb5, 0xcd, 0x58, 0x32, 0xdd, 0x9e, - 0x6a, 0xde, 0xe3, 0x53, -}; - -void aes_ext_flash_ctr_test(uint32_t output_buf_caps) -{ - mbedtls_aes_context ctx; - uint8_t nonce[16]; - uint8_t key[16]; - uint8_t stream_block[16]; - size_t SZ = sizeof(long_input); - memset(nonce, 0x2F, 16); - memset(key, 0x1E, 16); - - uint8_t *ciphertext = heap_caps_malloc(SZ, output_buf_caps); - uint8_t *decryptedtext = heap_caps_malloc(SZ, INTERNAL_DMA_CAPS); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - - size_t offset; - - // Encrypt with input buffer in external flash - offset = 0; - memset(nonce, 0x2F, 16); - mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, long_input, ciphertext); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_long_input_end, ciphertext + SZ - 32, 32); - - // Decrypt - offset = 0; - memset(nonce, 0x2F, 16); - // Decrypt with input buffer in external flash, the crypto DMA can't access this - mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, ciphertext, decryptedtext); - - TEST_ASSERT_EQUAL_HEX8_ARRAY(long_input, decryptedtext, SZ); - - mbedtls_aes_free(&ctx); - free(ciphertext); - free(decryptedtext); -} - -/* Tests how crypto DMA handles data in external memory */ -TEST_CASE("mbedtls AES PSRAM tests", "[aes]") -{ - aes_ctr_alignment_test(INTERNAL_DMA_CAPS, PSRAM_DMA_CAPS); - aes_ctr_alignment_test(PSRAM_DMA_CAPS, INTERNAL_DMA_CAPS); - aes_ctr_alignment_test(PSRAM_DMA_CAPS, PSRAM_DMA_CAPS); - aes_psram_one_buf_ctr_test(); - aes_ctr_stream_test(INTERNAL_DMA_CAPS, PSRAM_DMA_CAPS, TEST_AES_CTR_STREAM_DMA_MODE_LEN); - aes_ctr_stream_test(PSRAM_DMA_CAPS, INTERNAL_DMA_CAPS, TEST_AES_CTR_STREAM_DMA_MODE_LEN); - aes_ctr_stream_test(PSRAM_DMA_CAPS, PSRAM_DMA_CAPS, TEST_AES_CTR_STREAM_DMA_MODE_LEN); -} - -/* Tests how crypto DMA handles data from external flash */ -TEST_CASE("mbedtls AES external flash tests", "[aes]") -{ - aes_ext_flash_ctr_test(PSRAM_DMA_CAPS); - aes_ext_flash_ctr_test(INTERNAL_DMA_CAPS); -} -#endif // CONFIG_SPIRAM_USE_MALLOC - - -static SemaphoreHandle_t done_sem; - -static void __attribute__((unused)) aes_ctr_stream_test_task(void *pv) -{ - aes_ctr_stream_test(INTERNAL_DMA_CAPS, INTERNAL_DMA_CAPS, TEST_AES_CTR_STREAM_DMA_MODE_LEN); - xSemaphoreGive(done_sem); - vTaskDelete(NULL); -} - -#if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK && !CONFIG_IDF_TARGET_ESP32H2 -// Not enough rtc memory for test on H2 - -TEST_CASE("mbedtls AES stack in RTC RAM", "[mbedtls]") -{ - done_sem = xSemaphoreCreateBinary(); - static StaticTask_t rtc_task; - size_t STACK_SIZE = 3072; - uint8_t *rtc_stack = heap_caps_calloc(STACK_SIZE, 1, MALLOC_CAP_RTCRAM); - TEST_ASSERT(esp_ptr_in_rtc_dram_fast(rtc_stack)); - - TEST_ASSERT_NOT_NULL(xTaskCreateStatic(aes_ctr_stream_test_task, "aes_ctr_task", STACK_SIZE, NULL, - 3, rtc_stack, &rtc_task)); - TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)); - - /* Give task time to cleanup before freeing stack */ - vTaskDelay(1000 / portTICK_PERIOD_MS); - free(rtc_stack); - - vSemaphoreDelete(done_sem); -} - -#endif //CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK && !CONFIG_IDF_TARGET_ESP32H2 - -#if CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM && CONFIG_SPIRAM_USE_MALLOC - -TEST_CASE("mbedtls AES stack in PSRAM", "[mbedtls]") -{ - done_sem = xSemaphoreCreateBinary(); - static StaticTask_t psram_task; - size_t STACK_SIZE = 3072; - uint8_t *psram_stack = heap_caps_calloc(STACK_SIZE, 1, PSRAM_DMA_CAPS); - - TEST_ASSERT(esp_ptr_external_ram(psram_stack)); - - TEST_ASSERT_NOT_NULL(xTaskCreateStatic(aes_ctr_stream_test_task, "aes_ctr_task", STACK_SIZE, NULL, - 3, psram_stack, &psram_task)); - TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)); - - /* Give task time to cleanup before freeing stack */ - vTaskDelay(1000 / portTICK_PERIOD_MS); - free(psram_stack); - - vSemaphoreDelete(done_sem); -} - -#endif //CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM && CONFIG_SPIRAM_USE_MALLOC diff --git a/components/mbedtls/test_apps/main/test_aes_gcm.c b/components/mbedtls/test_apps/main/test_aes_gcm.c deleted file mode 100644 index c0b3a068233..00000000000 --- a/components/mbedtls/test_apps/main/test_aes_gcm.c +++ /dev/null @@ -1,885 +0,0 @@ -/* mbedTLS GCM test - * - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include -#include -#include "mbedtls/aes.h" -#include "mbedtls/gcm.h" -#include "unity.h" -#include "sdkconfig.h" -#include "esp_heap_caps.h" -#include "test_utils.h" -#include "ccomp_timer.h" -#include "sys/param.h" - -#if CONFIG_MBEDTLS_HARDWARE_AES - -/* - Python example code for generating test vectors - - import os, binascii - from cryptography.hazmat.primitives.ciphers.aead import AESGCM - - def as_c_array(byte_arr): - hex_str = '' - for idx, byte in enumerate(byte_arr): - hex_str += "0x{:02x}, ".format(byte) - bytes_per_line = 8 - if idx % bytes_per_line == bytes_per_line - 1: - hex_str += '\n' - - return hex_str - - key = b'\x44' * 16 - iv = b'\xEE' * 16 - data = b'\xAA' * 3200 - aad = b'\x76' * 16 - - aesgcm = AESGCM(key) - - ct = aesgcm.encrypt(iv, data, aad) - - print(as_c_array(ct)) -*/ - -TEST_CASE("mbedtls GCM stream test", "[aes-gcm]") -{ - - const unsigned SZ = 100; - mbedtls_gcm_context ctx; - uint8_t nonce[16]; - uint8_t key[16]; - uint8_t tag[16]; - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - - const uint8_t expected_cipher[] = { - 0x03, 0x92, 0x13, 0x49, 0x1f, 0x1f, 0x24, 0x41, - 0xe8, 0xeb, 0x89, 0x47, 0x50, 0x0a, 0xce, 0xa3, - 0xc7, 0x1c, 0x10, 0x70, 0xb0, 0x89, 0x82, 0x5e, - 0x0f, 0x4a, 0x23, 0xee, 0xd2, 0xfc, 0xff, 0x45, - 0x61, 0x4c, 0xd1, 0xfb, 0x6d, 0xe2, 0xbe, 0x67, - 0x6f, 0x94, 0x72, 0xa3, 0xe7, 0x04, 0x99, 0xb3, - 0x4a, 0x46, 0xf9, 0x2b, 0xaf, 0xac, 0xa9, 0x0e, - 0x43, 0x7e, 0x8b, 0xc4, 0xbf, 0x49, 0xa4, 0x83, - 0x9c, 0x31, 0x11, 0x1c, 0x09, 0xac, 0x90, 0xdf, - 0x00, 0x34, 0x08, 0xe5, 0x70, 0xa3, 0x7e, 0x4b, - 0x36, 0x48, 0x5a, 0x3f, 0x28, 0xc7, 0x1c, 0xd9, - 0x1b, 0x1b, 0x49, 0x96, 0xe9, 0x7c, 0xea, 0x54, - 0x7c, 0x71, 0x29, 0x0d - }; - const uint8_t expected_tag[] = { - 0x35, 0x1c, 0x21, 0xc6, 0xbc, 0x6b, 0x18, 0x52, - 0x90, 0xe1, 0xf2, 0x5b, 0xe1, 0xf6, 0x15, 0xee, - }; - - - memset(nonce, 0x89, 16); - memset(key, 0x56, 16); - - // allocate internal memory - uint8_t *ciphertext = heap_caps_malloc(SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - uint8_t *plaintext = heap_caps_malloc(SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - uint8_t *decryptedtext = heap_caps_malloc(SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(plaintext); - TEST_ASSERT_NOT_NULL(decryptedtext); - - memset(plaintext, 0xAB, SZ); - /* Test that all the end results are the same - no matter how many bytes we encrypt each call - */ - for (int bytes_to_process = 16; bytes_to_process < SZ; bytes_to_process = bytes_to_process + 16) { - memset(nonce, 0x89, 16); - memset(ciphertext, 0x0, SZ); - memset(decryptedtext, 0x0, SZ); - memset(tag, 0x0, 16); - - mbedtls_gcm_init(&ctx); - mbedtls_gcm_setkey(&ctx, cipher, key, 128); - mbedtls_gcm_starts( &ctx, MBEDTLS_AES_ENCRYPT, nonce, sizeof(nonce) ); - mbedtls_gcm_update_ad( &ctx, NULL, 0 ); - - size_t olen; - // Encrypt - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - size_t length = (idx + bytes_to_process > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_gcm_update(&ctx, plaintext + idx, length, ciphertext + idx, length, &olen); - } - mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag, sizeof(tag) ); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_tag, tag, sizeof(tag)); - - // Decrypt - memset(nonce, 0x89, 16); - mbedtls_gcm_free( &ctx ); - - mbedtls_gcm_init(&ctx); - mbedtls_gcm_setkey(&ctx, cipher, key, 128); - mbedtls_gcm_starts( &ctx, MBEDTLS_AES_DECRYPT, nonce, sizeof(nonce)); - mbedtls_gcm_update_ad( &ctx, NULL, 0 ); - - for (int idx = 0; idx < SZ; idx = idx + bytes_to_process) { - // Limit length of last call to avoid exceeding buffer size - - size_t length = (idx + bytes_to_process > SZ) ? (SZ - idx) : bytes_to_process; - mbedtls_gcm_update(&ctx, ciphertext + idx, length, decryptedtext + idx, length, &olen); - } - mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag, sizeof(tag) ); - TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - mbedtls_gcm_free( &ctx ); - } - free(plaintext); - free(ciphertext); - free(decryptedtext); -} - -TEST_CASE("mbedtls AES GCM self-tests", "[aes-gcm]") -{ - TEST_ASSERT_FALSE_MESSAGE(mbedtls_gcm_self_test(1), "AES GCM self-test should pass."); -} - -typedef struct { - uint8_t *plaintext; - size_t plaintext_length; - uint32_t output_caps; - uint8_t *add_buf; - size_t add_length; - uint8_t *iv; - size_t iv_length; - uint8_t *key; - size_t key_bits; - size_t tag_len; -} aes_gcm_test_cfg_t; - -typedef struct { - const uint8_t *expected_tag; - const uint8_t *ciphertext_last_block; // Last block of the ciphertext -} aes_gcm_test_expected_res_t; - - -typedef enum { - AES_GCM_TEST_CRYPT_N_TAG, - AES_GCM_TEST_START_UPDATE_FINISH, -} aes_gcm_test_type_t; - -static void aes_gcm_test(aes_gcm_test_cfg_t *cfg, aes_gcm_test_expected_res_t *res, aes_gcm_test_type_t aes_gcm_type) -{ - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - mbedtls_gcm_context ctx; - - uint8_t tag_buf_encrypt[16] = {}; - uint8_t tag_buf_decrypt[16] = {}; - uint8_t iv_buf[16] = {}; - - uint8_t *ciphertext = heap_caps_malloc(cfg->plaintext_length, cfg->output_caps); - uint8_t *output = heap_caps_malloc(cfg->plaintext_length, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - - if (cfg->plaintext_length != 0) { - TEST_ASSERT_NOT_NULL(ciphertext); - TEST_ASSERT_NOT_NULL(output); - } - - memset(ciphertext, 0, cfg->plaintext_length); - memset(output, 0, cfg->plaintext_length); - memcpy(iv_buf, cfg->iv, cfg->iv_length); - - mbedtls_gcm_init(&ctx); - mbedtls_gcm_setkey(&ctx, cipher, cfg->key, cfg->key_bits); - size_t olen; - /* Encrypt and tag */ - if (aes_gcm_type == AES_GCM_TEST_CRYPT_N_TAG) { - mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_AES_ENCRYPT, cfg->plaintext_length, iv_buf, cfg->iv_length, cfg->add_buf, cfg->add_length, cfg->plaintext, ciphertext, cfg->tag_len, tag_buf_encrypt); - } else if (aes_gcm_type == AES_GCM_TEST_START_UPDATE_FINISH) { - TEST_ASSERT(mbedtls_gcm_starts( &ctx, MBEDTLS_AES_ENCRYPT, iv_buf, cfg->iv_length) == 0 ); - TEST_ASSERT(mbedtls_gcm_update_ad( &ctx, cfg->add_buf, cfg->add_length) == 0 ); - TEST_ASSERT(mbedtls_gcm_update( &ctx, cfg->plaintext, cfg->plaintext_length, ciphertext, cfg->plaintext_length, &olen) == 0 ); - TEST_ASSERT(mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf_encrypt, cfg->tag_len) == 0 ); - } - size_t offset = cfg->plaintext_length > 16 ? cfg->plaintext_length - 16 : 0; - /* Sanity check: make sure the last ciphertext block matches what we expect to see. */ - TEST_ASSERT_EQUAL_HEX8_ARRAY(res->ciphertext_last_block, ciphertext + offset, MIN(16, cfg->plaintext_length)); - TEST_ASSERT_EQUAL_HEX8_ARRAY(res->expected_tag, tag_buf_encrypt, cfg->tag_len); - - - /* Decrypt and authenticate */ - if (aes_gcm_type == AES_GCM_TEST_CRYPT_N_TAG) { - TEST_ASSERT(mbedtls_gcm_auth_decrypt(&ctx, cfg->plaintext_length, iv_buf, cfg->iv_length, cfg->add_buf, cfg->add_length, res->expected_tag, cfg->tag_len, ciphertext, output) == 0); - } else if (aes_gcm_type == AES_GCM_TEST_START_UPDATE_FINISH) { - TEST_ASSERT(mbedtls_gcm_starts( &ctx, MBEDTLS_AES_DECRYPT, iv_buf, cfg->iv_length) == 0 ); - TEST_ASSERT(mbedtls_gcm_update_ad( &ctx, cfg->add_buf, cfg->add_length) == 0 ); - TEST_ASSERT(mbedtls_gcm_update( &ctx, ciphertext, cfg->plaintext_length, output, cfg->plaintext_length, &olen) == 0 ); - TEST_ASSERT(mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf_decrypt, cfg->tag_len) == 0 ); - - /* mbedtls_gcm_auth_decrypt already checks tag so only needed for AES_GCM_TEST_START_UPDATE_FINISH */ - TEST_ASSERT_EQUAL_HEX8_ARRAY(res->expected_tag, tag_buf_decrypt, cfg->tag_len); - } - - TEST_ASSERT_EQUAL_HEX8_ARRAY(cfg->plaintext, output, cfg->plaintext_length); - mbedtls_gcm_free( &ctx ); - free(ciphertext); - free(output); -} - - - -TEST_CASE("mbedtls AES GCM", "[aes-gcm]") -{ - uint8_t iv[16]; - uint8_t key[16]; - uint8_t add[30]; - - memset(iv, 0xB1, sizeof(iv)); - memset(key, 0x27, sizeof(key)); - memset(add, 0x90, sizeof(add)); - - size_t length[] = {10, 16, 500, 5000, 12345}; - - const uint8_t expected_last_block[][16] = { - - { - 0x37, 0x99, 0x4b, 0x16, 0x5f, 0x8d, 0x27, 0xb1, - 0x60, 0x72 - }, - - { - 0x37, 0x99, 0x4b, 0x16, 0x5f, 0x8d, 0x27, 0xb1, - 0x60, 0x72, 0x9a, 0x81, 0x8d, 0x3c, 0x69, 0x66 - }, - - { - 0x9d, 0x7a, 0xac, 0x84, 0xe3, 0x70, 0x43, 0x0f, - 0xa7, 0x83, 0x43, 0xc9, 0x04, 0xf8, 0x7d, 0x48 - }, - - { - 0xee, 0xfd, 0xab, 0x2a, 0x09, 0x44, 0x41, 0x6a, - 0x91, 0xb0, 0x74, 0x24, 0xee, 0x35, 0xb1, 0x39 - }, - - { - 0x51, 0xf7, 0x1f, 0x67, 0x1a, 0x4a, 0x12, 0x37, - 0x60, 0x3b, 0x68, 0x01, 0x20, 0x4f, 0xf3, 0xd9 - }, - }; - - const uint8_t expected_tag[][16] = { - - { - 0x06, 0x4f, 0xb5, 0x91, 0x12, 0x24, 0xb4, 0x24, - 0x0b, 0xc2, 0x85, 0x59, 0x6a, 0x7c, 0x1f, 0xc9 - }, - - { - 0x45, 0xc2, 0xa8, 0xfe, 0xff, 0x49, 0x1f, 0x45, - 0x8e, 0x29, 0x74, 0x41, 0xed, 0x9b, 0x54, 0x28 - }, - - { - 0xe1, 0xf9, 0x40, 0xfa, 0x29, 0x6f, 0x30, 0xae, - 0xb6, 0x9b, 0x33, 0xdb, 0x8a, 0xf9, 0x70, 0xc4 - }, - - { - 0x22, 0xe1, 0x22, 0x34, 0x0c, 0x91, 0x0b, 0xcf, - 0xa3, 0x42, 0xe0, 0x48, 0xe6, 0xfe, 0x2e, 0x28 - }, - - { - 0xfb, 0xfe, 0x5a, 0xed, 0x26, 0x5c, 0x5e, 0x66, - 0x4e, 0xb2, 0x48, 0xce, 0xe9, 0x88, 0x1c, 0xe0 - }, - }; - - aes_gcm_test_cfg_t cfg = { - .output_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, - .iv = iv, - .iv_length = sizeof(iv), - .key = key, - .key_bits = 8 * sizeof(key), - .add_buf = add, - .add_length = sizeof(add), - .tag_len = 16 - }; - - aes_gcm_test_expected_res_t res = { - }; - - for (int i = 0; i < sizeof(length) / sizeof(length[0]); i++) { - printf("Test AES-GCM with plaintext length = %d\n", length[i]); - uint8_t *input = heap_caps_malloc(length[i], MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - TEST_ASSERT(input != NULL || length[i] == 0); - memset(input, 0x36, length[i]); - - cfg.plaintext = input; - cfg.plaintext_length = length[i]; - res.expected_tag = expected_tag[i]; - res.ciphertext_last_block = expected_last_block[i], - - aes_gcm_test(&cfg, &res, AES_GCM_TEST_CRYPT_N_TAG); - aes_gcm_test(&cfg, &res, AES_GCM_TEST_START_UPDATE_FINISH); - - free(input); - } -} - - -TEST_CASE("mbedtls AES GCM - Different add messages", "[aes-gcm]") -{ - const unsigned CALL_SZ = 160; - uint8_t iv[16]; - uint8_t key[16]; - uint8_t *input = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(input); - - memset(input, 0x67, CALL_SZ); - memset(iv, 0xA2, sizeof(iv)); - memset(key, 0x48, sizeof(key)); - - const uint8_t expected_last_block[] = { - 0xcd, 0xb9, 0xad, 0x6f, 0xc9, 0x35, 0x21, 0x0d, - 0xc9, 0x5d, 0xea, 0xd9, 0xf7, 0x1d, 0x43, 0xed - }; - - size_t add_len[] = {0, 10, 16, 500, 5000}; - - const uint8_t expected_tag[][16] = { - { - 0xe3, 0x91, 0xad, 0x40, 0x96, 0xb7, 0x8c, 0x53, - 0x4d, 0x15, 0x7d, 0x55, 0x15, 0xdf, 0x10, 0x69 - }, - - { - 0xc2, 0x38, 0x36, 0xe9, 0x12, 0x72, 0x5b, 0x31, - 0x0c, 0xde, 0xb5, 0xc9, 0x8c, 0xa3, 0xcb, 0xe7 - }, - - { - 0x57, 0x10, 0x22, 0x91, 0x65, 0xfa, 0x89, 0xba, - 0x0a, 0x3e, 0xc1, 0x7c, 0x93, 0x6e, 0x35, 0xac - }, - - { - 0x3c, 0x28, 0x03, 0xc2, 0x14, 0x40, 0xec, 0xb6, - 0x25, 0xfb, 0xdd, 0x55, 0xa0, 0xb2, 0x47, 0x7b - }, - - { - 0xfa, 0x66, 0x4a, 0x97, 0x2d, 0x02, 0x32, 0x5b, - 0x92, 0x94, 0xf1, 0x00, 0x1c, 0xfa, 0xe3, 0x07 - } - }; - - aes_gcm_test_cfg_t cfg = { - .plaintext = input, - .plaintext_length = CALL_SZ, - .output_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, - .iv = iv, - .iv_length = sizeof(iv), - .key = key, - .key_bits = 8 * sizeof(key), - .tag_len = 16 - }; - - aes_gcm_test_expected_res_t res = { - .ciphertext_last_block = expected_last_block, - }; - - for (int i = 0; i < sizeof(add_len) / sizeof(add_len[0]); i++) { - printf("Test AES-GCM with add length = %d\n", add_len[i]); - uint8_t *add = heap_caps_malloc(add_len[i], MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - TEST_ASSERT(add != NULL || add_len[i] == 0); - memset(add, 0x12, add_len[i]); - - cfg.add_buf = add; - cfg.add_length = add_len[i]; - res.expected_tag = expected_tag[i]; - - aes_gcm_test(&cfg, &res, AES_GCM_TEST_CRYPT_N_TAG); - aes_gcm_test(&cfg, &res, AES_GCM_TEST_START_UPDATE_FINISH); - - free(add); - } - free(input); -} - - - -TEST_CASE("mbedtls AES GCM performance, start, update, ret", "[aes-gcm]") -{ - const unsigned CALL_SZ = 16 * 3200; - mbedtls_gcm_context ctx; - float elapsed_usec; - unsigned char tag_buf[16]; - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - uint8_t iv[16]; - uint8_t key[16]; - uint8_t aad[16]; - size_t olen; - memset(iv, 0xEE, 16); - memset(key, 0x44, 16); - memset(aad, 0x76, 16); - - // 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); - - mbedtls_gcm_init(&ctx); - mbedtls_gcm_setkey( &ctx, cipher, key, 128); - - ccomp_timer_start(); - - memset(buf, 0xAA, CALL_SZ); - - TEST_ASSERT(mbedtls_gcm_starts( &ctx, MBEDTLS_AES_ENCRYPT, iv, sizeof(iv) ) == 0 ); - TEST_ASSERT(mbedtls_gcm_update_ad( &ctx, aad, sizeof(aad)) == 0 ); - TEST_ASSERT(mbedtls_gcm_update( &ctx, buf, CALL_SZ, buf, CALL_SZ, &olen) == 0 ); - TEST_ASSERT(mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 ) == 0 ); - - elapsed_usec = ccomp_timer_stop(); - - /* Sanity check: make sure the last ciphertext block matches - what we expect to see. - */ - const uint8_t expected_last_block[] = { - 0xd4, 0x25, 0x88, 0xd4, 0x32, 0x52, 0x3d, 0x6f, - 0xae, 0x49, 0x19, 0xb5, 0x95, 0x01, 0xde, 0x7d, - }; - - const uint8_t expected_tag[] = { - 0xf5, 0x10, 0x1f, 0x21, 0x5b, 0x07, 0x0d, 0x3f, - 0xac, 0xc9, 0xd0, 0x42, 0x45, 0xef, 0xc7, 0xfa, - }; - - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_tag, tag_buf, 16); - - free(buf); - - // bytes/usec = MB/sec - float mb_sec = CALL_SZ / elapsed_usec; - printf("GCM encryption rate %.3fMB/sec\n", mb_sec); - -#ifdef CONFIG_MBEDTLS_HARDWARE_GCM - // Don't put a hard limit on software AES performance - TEST_PERFORMANCE_CCOMP_GREATER_THAN(AES_GCM_UPDATE_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec); -#endif -} - - -TEST_CASE("mbedtls AES GCM performance, crypt-and-tag", "[aes-gcm]") -{ - const unsigned CALL_SZ = 16 * 3200; - mbedtls_gcm_context ctx; - float elapsed_usec; - unsigned char tag_buf[16] = {}; - mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; - uint8_t iv[16]; - uint8_t key[16]; - uint8_t aad[16]; - - memset(iv, 0xEE, 16); - memset(key, 0x44, 16); - memset(aad, 0x76, 16); - - // 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); - - mbedtls_gcm_init(&ctx); - mbedtls_gcm_setkey( &ctx, cipher, key, 128); - - memset(buf, 0xAA, CALL_SZ); - - ccomp_timer_start(); - mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_AES_ENCRYPT, CALL_SZ, iv, sizeof(iv), aad, sizeof(aad), buf, buf, 16, tag_buf); - - elapsed_usec = ccomp_timer_stop(); - - /* Sanity check: make sure the last ciphertext block matches - what we expect to see. - */ - - const uint8_t expected_last_block[] = { - 0xd4, 0x25, 0x88, 0xd4, 0x32, 0x52, 0x3d, 0x6f, - 0xae, 0x49, 0x19, 0xb5, 0x95, 0x01, 0xde, 0x7d, - }; - - const uint8_t expected_tag[] = { - 0xf5, 0x10, 0x1f, 0x21, 0x5b, 0x07, 0x0d, 0x3f, - 0xac, 0xc9, 0xd0, 0x42, 0x45, 0xef, 0xc7, 0xfa, - }; - - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16); - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_tag, tag_buf, 16); - - free(buf); - - // bytes/usec = MB/sec - float mb_sec = CALL_SZ / elapsed_usec; - printf("GCM encryption rate %.3fMB/sec\n", mb_sec); - -#ifdef CONFIG_MBEDTLS_HARDWARE_GCM - // Don't put a hard limit on software AES performance - TEST_PERFORMANCE_CCOMP_GREATER_THAN(AES_GCM_CRYPT_TAG_THROUGHPUT_MBSEC, "%.3fMB/sec", mb_sec); -#endif -} - -TEST_CASE("mbedtls AES GCM - Combine different IV/Key/Plaintext/AAD lengths", "[aes-gcm]") -{ - #define IV_BYTES_VALUE 0xA2 - #define KEY_BYTES_VALUE 0x48 - #define INPUT_BYTES_VALUE 0x36 - #define ADD_BYTES_VALUE 0x12 - - uint8_t iv[16]; - uint8_t key[32]; - - memset(iv, IV_BYTES_VALUE, sizeof(iv)); - memset(key, KEY_BYTES_VALUE, sizeof(key)); - - /* Key length is: 16 bytes, 32 bytes */ - size_t key_length[] = {16, 32}; - - /* IV length is: 12 bytes (standard), 16 bytes */ - size_t iv_length[] = {12, 16}; - - /* Plaintext length is: a multiple of 16 bytes, a non-multiple of 16 bytes */ - size_t length[] = {160, 321}; - - /* Add len is: 0, a multiple of 16 bytes, a non-multiple of 16 bytes */ - size_t add_len[] = {0, 160, 321}; - - /*indexes: Key - IV - Plaintext */ - const uint8_t expected_last_block[2][2][2][16] = { - { - /* 16 byte key */ - - { - { - 0xa2, 0x1e, 0x23, 0x3c, 0xfc, 0x7c, 0xec, 0x9a, - 0x91, 0xe5, 0xdb, 0x3a, 0xe5, 0x0c, 0x3f, 0xc2, - }, - - { - 0xa8, 0xeb, 0x40, 0x9b, 0x7b, 0x87, 0x07, - 0x68, 0x17, 0x5c, 0xc0, 0xb7, 0xb4, 0xb3, 0x81, - 0xbe, - } - }, - { - { - 0x9c, 0xe8, 0xfc, 0x3e, 0x98, 0x64, 0x70, 0x5c, - 0x98, 0x0c, 0xbb, 0x88, 0xa6, 0x4c, 0x12, 0xbc - }, - - { - 0x8b, 0x66, 0xf5, 0xbc, 0x56, 0x59, 0xae, - 0xf0, 0x9e, 0x5c, 0xdb, 0x6d, 0xfc, 0x1f, 0x2e, - 0x00 - } - }, - }, - { - /* 32 byte key */ - { - { - 0xde, 0xc2, 0xd3, 0xeb, 0x5e, 0x03, 0x53, 0x4b, - 0x04, 0x0d, 0x63, 0xf1, 0xd8, 0x5b, 0x1f, 0x85, - }, - - { - 0xb5, 0x53, 0x8e, 0xd3, 0xab, 0x10, 0xf1, - 0x77, 0x41, 0x92, 0xea, 0xdd, 0xdd, 0x9e, 0x5d, - 0x40, - } - }, - { - { - 0x3b, 0xc7, 0xf0, 0x3f, 0xba, 0x97, 0xbd, 0xa0, - 0xa5, 0x48, 0xf3, 0x7a, 0xde, 0x23, 0x19, 0x7a, - }, - - { - 0x57, 0xc7, 0x4d, 0xe3, 0x79, 0x5e, 0xbd, - 0x0d, 0xd7, 0x6a, 0xef, 0x1f, 0x54, 0x29, 0xa6, - 0xd7, - } - }, - }, - }; - - /*indexes: Key - IV - Plaintext - Add len*/ - const uint8_t expected_tag[2][2][2][3][16] = { - { - { - { - // Plaintext 160 bytes - { - 0x67, 0x92, 0xb1, 0x7f, 0x44, 0x1f, 0x95, 0xfb, - 0x33, 0x76, 0x66, 0xb7, 0x4f, 0x3e, 0xec, 0x4d, - }, - - { - 0xb1, 0x99, 0xed, 0x1b, 0x4e, 0x12, 0x87, 0x5e, - 0xf4, 0xe3, 0x81, 0xd8, 0x96, 0x07, 0xda, 0xff, - }, - - { - 0x73, 0x35, 0x0c, 0xf5, 0x70, 0x1e, 0xc0, 0x99, - 0x34, 0xba, 0x1a, 0x50, 0x23, 0xac, 0x21, 0x33, - }, - }, - { - // Plaintext 321 bytes - { - 0x2d, 0xf6, 0xd0, 0x7a, 0x75, 0x4d, 0x9d, - 0xb5, 0x9d, 0x43, 0xbf, 0x57, 0x10, 0xa3, 0xff, - 0x3d - }, - - { - 0x06, 0x91, 0xe4, 0x38, 0x3a, 0xe1, 0x6e, - 0x2d, 0x83, 0x68, 0x2e, 0xb0, 0x26, 0x2f, 0xe4, - 0x78 - }, - - { - 0x1b, 0x58, 0x2f, 0x9b, 0xe9, 0xe0, 0xe0, - 0x43, 0x83, 0x08, 0xec, 0x58, 0x3a, 0x78, 0xe9, - 0x69, - } - } - }, - { - { - // Plaintext 160 bytes - { - 0x77, 0xe5, 0x2e, 0x2d, 0x94, 0xb8, 0x03, 0x61, - 0x7a, 0xd5, 0x0c, 0x3c, 0x9c, 0x40, 0x92, 0x9b - }, - - { - 0xa1, 0xee, 0x72, 0x49, 0x9e, 0xb5, 0x11, 0xc4, - 0xbd, 0x40, 0xeb, 0x53, 0x45, 0x79, 0xa4, 0x29 - }, - - { - 0x63, 0x42, 0x93, 0xa7, 0xa0, 0xb9, 0x56, 0x03, - 0x7d, 0x19, 0x70, 0xdb, 0xf0, 0xd2, 0x5f, 0xe5 - }, - }, - { - // Plaintext 321 bytes - { - 0x50, 0xa3, 0x79, 0xfc, 0x17, 0xb8, 0xf4, - 0xf6, 0x14, 0xaa, 0x4a, 0xe7, 0xd4, 0xa0, 0xea, - 0xee - }, - - { - 0x7b, 0xc4, 0x4d, 0xbe, 0x58, 0x14, 0x07, - 0x6e, 0x0a, 0x81, 0xdb, 0x00, 0xe2, 0x2c, 0xf1, - 0xab - }, - - { - 0x66, 0x0d, 0x86, 0x1d, 0x8b, 0x15, 0x89, - 0x00, 0x0a, 0xe1, 0x19, 0xe8, 0xfe, 0x7b, 0xfc, - 0xba - } - } - }, - }, - { - { - { - // Plaintext 160 bytes - { - 0x04, 0x04, 0x15, 0xb1, 0xd3, 0x98, 0x15, 0x45, - 0xa2, 0x44, 0xba, 0x4a, 0xde, 0xc2, 0x8d, 0xd6, - }, - - { - 0x94, 0x3e, 0xc3, 0x5d, 0xdc, 0x42, 0xf6, 0x4c, - 0x80, 0x15, 0xe4, 0xb9, 0x0b, 0xc9, 0x87, 0x01, - }, - - { - 0x93, 0x6e, 0x26, 0x5b, 0x7e, 0x17, 0xc8, 0x73, - 0x9b, 0x71, 0x31, 0x7a, 0x8b, 0x0e, 0x19, 0x89, - } - }, - { - // Plaintext 321 bytes - { - 0x99, 0x5e, 0x77, 0x28, 0x8b, 0xa8, 0x9b, - 0xb3, 0x35, 0xc3, 0x99, 0x90, 0xd4, 0x5d, 0x63, - 0xa7, - }, - - { - 0xbc, 0xc2, 0x9f, 0xe6, 0x38, 0xef, 0xf5, - 0x11, 0x76, 0x09, 0x17, 0x3a, 0xd4, 0x91, 0xee, - 0xfe, - }, - - { - 0x9f, 0xa6, 0x23, 0x5a, 0x4d, 0x78, 0xae, - 0xce, 0x10, 0x35, 0xc1, 0x0c, 0x6e, 0xc2, 0x4e, - 0xe8, - } - } - }, - { - { - // Plaintext 160 bytes - { - 0xfb, 0x74, 0x7e, 0x21, 0xf2, 0xe7, 0xe3, 0xf5, - 0xfa, 0xc8, 0x23, 0xab, 0x54, 0x9a, 0xb9, 0xcf, - }, - - { - 0x6b, 0x4e, 0xa8, 0xcd, 0xfd, 0x3d, 0x00, 0xfc, - 0xd8, 0x99, 0x7d, 0x58, 0x81, 0x91, 0xb3, 0x18, - }, - - { - 0x6c, 0x1e, 0x4d, 0xcb, 0x5f, 0x68, 0x3e, 0xc3, - 0xc3, 0xfd, 0xa8, 0x9b, 0x01, 0x56, 0x2d, 0x90, - }, - }, - { - // Plaintext 321 bytes - { - 0xcd, 0x49, 0x75, 0x4c, 0x2a, 0x62, 0x65, - 0x6f, 0xfe, 0x14, 0xc2, 0x5d, 0x41, 0x07, 0x24, - 0x55 - }, - - { - 0xe8, 0xd5, 0x9d, 0x82, 0x99, 0x25, 0x0b, - 0xcd, 0xbd, 0xde, 0x4c, 0xf7, 0x41, 0xcb, 0xa9, - 0x0c, - }, - - { - 0xcb, 0xb1, 0x21, 0x3e, 0xec, 0xb2, 0x50, - 0x12, 0xdb, 0xe2, 0x9a, 0xc1, 0xfb, 0x98, 0x09, - 0x1a, - } - } - }, - }, - }; - - aes_gcm_test_cfg_t cfg = { - .output_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, - .tag_len = 16 - }; - - - for (int i_key = 0; i_key < sizeof(key_length) / sizeof(key_length[0]); i_key++) { - printf("Test AES-GCM with key length = %d\n", key_length[i_key]); - - cfg.key = key; - cfg.key_bits = 8 * key_length[i_key]; - - for (int i_iv = 0; i_iv < sizeof(iv_length) / sizeof(iv_length[0]); i_iv++) { - printf("Test AES-GCM with IV length = %d\n", iv_length[i_iv]); - - cfg.iv = iv; - cfg.iv_length = iv_length[i_iv]; - - for (int i_len = 0; i_len < sizeof(length) / sizeof(length[0]); i_len++) { - printf("Test AES-GCM with plaintext length = %d\n", length[i_len]); - uint8_t *input = heap_caps_malloc(length[i_len], MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - TEST_ASSERT(input != NULL || length[i_len] == 0); - memset(input, INPUT_BYTES_VALUE, length[i_len]); - cfg.plaintext = input; - cfg.plaintext_length = length[i_len]; - - aes_gcm_test_expected_res_t res = {0}; - - for (int i_add = 0; i_add < sizeof(add_len) / sizeof(add_len[0]); i_add++) { - - printf("Test AES-GCM with add length = %d\n", add_len[i_add]); - uint8_t *add = heap_caps_malloc(add_len[i_add], MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - TEST_ASSERT(add != NULL || add_len[i_add] == 0); - memset(add, ADD_BYTES_VALUE, add_len[i_add]); - - cfg.add_buf = add; - cfg.add_length = add_len[i_add]; - - res.expected_tag = expected_tag[i_key][i_iv][i_len][i_add]; - res.ciphertext_last_block = expected_last_block[i_key][i_iv][i_len], - - aes_gcm_test(&cfg, &res, AES_GCM_TEST_CRYPT_N_TAG); - - free(add); - } - free(input); - } - } - } -} - -TEST_CASE("mbedtls AES GCM - Different Authentication Tag lengths", "[aes-gcm]") -{ - const unsigned CALL_SZ = 160; - uint8_t iv[16]; - uint8_t key[16]; - uint8_t aad[16]; - uint8_t *input = heap_caps_malloc(CALL_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(input); - - memset(input, 0x67, CALL_SZ); - memset(iv, 0xA2, sizeof(iv)); - memset(key, 0x48, sizeof(key)); - memset(aad, 0x12, sizeof(aad)); - - size_t tag_len[] = {4, 8, 11, 16}; - - const uint8_t expected_last_block[] = { - 0xcd, 0xb9, 0xad, 0x6f, 0xc9, 0x35, 0x21, 0x0d, - 0xc9, 0x5d, 0xea, 0xd9, 0xf7, 0x1d, 0x43, 0xed - }; - - const uint8_t expected_tag[16] = { - 0x57, 0x10, 0x22, 0x91, 0x65, 0xfa, 0x89, 0xba, - 0x0a, 0x3e, 0xc1, 0x7c, 0x93, 0x6e, 0x35, 0xac - }; - - aes_gcm_test_cfg_t cfg = { - .plaintext = input, - .plaintext_length = CALL_SZ, - .output_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, - .add_buf = aad, - .add_length = sizeof(aad), - .iv = iv, - .iv_length = sizeof(iv), - .key = key, - .key_bits = 8 * sizeof(key), - }; - - aes_gcm_test_expected_res_t res = { - .expected_tag = expected_tag, - .ciphertext_last_block = expected_last_block, - }; - - for (int i = 0; i < sizeof(tag_len) / sizeof(tag_len[0]); i++) { - printf("Test AES-GCM with tag length = %d\n", tag_len[i]); - cfg.tag_len = tag_len[i]; - aes_gcm_test(&cfg, &res, AES_GCM_TEST_CRYPT_N_TAG); - aes_gcm_test(&cfg, &res, AES_GCM_TEST_START_UPDATE_FINISH); - } - free(input); -} - -#endif //CONFIG_MBEDTLS_HARDWARE_AES diff --git a/components/mbedtls/test_apps/main/test_aes_perf.c b/components/mbedtls/test_apps/main/test_aes_perf.c index 6ba8f15c109..95d884b2f7b 100644 --- a/components/mbedtls/test_apps/main/test_aes_perf.c +++ b/components/mbedtls/test_apps/main/test_aes_perf.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -9,8 +9,8 @@ #include #include #include -#include "mbedtls/aes.h" -#include "mbedtls/gcm.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include "psa/crypto.h" #include "unity.h" #include "sdkconfig.h" #include "esp_heap_caps.h" @@ -21,25 +21,48 @@ TEST_CASE("mbedtls AES performance", "[aes][timeout=60]") { const unsigned CALLS = 256; const unsigned CALL_SZ = 32 * 1024; - mbedtls_aes_context ctx; float elapsed_usec; uint8_t iv[16]; uint8_t key[16]; + psa_status_t status; + memset(iv, 0xEE, 16); memset(key, 0x44, 16); // 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); - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); + psa_key_id_t key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + status = psa_import_key(&attributes, key, sizeof(key), &key_id); + if (status != PSA_SUCCESS) { + TEST_FAIL_MESSAGE("Failed to import key"); + } + + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING); + if (status != PSA_SUCCESS) { + printf("Failed to setup AES encryption with status: %ld\n", status); + TEST_FAIL_MESSAGE("Failed to setup AES encryption"); + } + + status = psa_cipher_set_iv(&operation, iv, sizeof(iv)); + if (status != PSA_SUCCESS) { + TEST_FAIL_MESSAGE("Failed to set IV for AES encryption"); + } ccomp_timer_start(); + size_t output_length = 0; for (int c = 0; c < CALLS; c++) { memset(buf, 0xAA, CALL_SZ); - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, CALL_SZ, iv, buf, buf); + psa_cipher_update(&operation, buf, CALL_SZ, buf, CALL_SZ, &output_length); } + psa_cipher_finish(&operation, buf + output_length, CALL_SZ - output_length, &output_length); elapsed_usec = ccomp_timer_stop(); /* Sanity check: make sure the last ciphertext block matches @@ -62,7 +85,8 @@ TEST_CASE("mbedtls AES performance", "[aes][timeout=60]") }; TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_last_block, buf + CALL_SZ - 16, 16); - mbedtls_aes_free(&ctx); + psa_destroy_key(key_id); + psa_reset_key_attributes(&attributes); free(buf); // bytes/usec = MB/sec diff --git a/components/mbedtls/test_apps/main/test_aes_sha_parallel.c b/components/mbedtls/test_apps/main/test_aes_sha_parallel.c index 453e5ca26db..40e146625a4 100644 --- a/components/mbedtls/test_apps/main/test_aes_sha_parallel.c +++ b/components/mbedtls/test_apps/main/test_aes_sha_parallel.c @@ -1,13 +1,11 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include -#include "mbedtls/aes.h" -#include "mbedtls/sha256.h" #include "unity.h" #include "sdkconfig.h" #include "esp_heap_caps.h" @@ -15,6 +13,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" +#include "psa/crypto.h" static SemaphoreHandle_t done_sem; @@ -27,18 +26,20 @@ static const uint8_t sha256_thousand_bs[32] = { static void tskRunSHA256Test(void *pvParameters) { - mbedtls_sha256_context sha256_ctx; unsigned char sha256[32]; - + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + psa_status_t status; + size_t hash_length = 0; for (int i = 0; i < 1000; i++) { - - mbedtls_sha256_init(&sha256_ctx); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false)); + status = psa_hash_setup(&operation, PSA_ALG_SHA_256); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); for (int j = 0; j < 10; j++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, (unsigned char *)one_hundred_bs, 100)); + status = psa_hash_update(&operation, (unsigned char *)one_hundred_bs, 100); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); } - TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256)); - mbedtls_sha256_free(&sha256_ctx); + status = psa_hash_finish(&operation, sha256, sizeof(sha256), &hash_length); + operation = psa_hash_operation_init(); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation"); } xSemaphoreGive(done_sem); @@ -60,10 +61,20 @@ static void tskRunAES256Test(void *pvParameters) 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, }; + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + psa_reset_key_attributes(&attributes); + for (int i = 0; i <1000; i++) { const unsigned SZ = 1600; - mbedtls_aes_context ctx; + psa_cipher_operation_t ctx = PSA_CIPHER_OPERATION_INIT; uint8_t nonce[16]; const uint8_t expected_cipher_end[] = { @@ -84,24 +95,28 @@ static void tskRunAES256Test(void *pvParameters) TEST_ASSERT_NOT_NULL(plaintext); TEST_ASSERT_NOT_NULL(decryptedtext); - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key_256, 256); + psa_cipher_encrypt_setup(&ctx, key_id, PSA_ALG_CBC_NO_PADDING); + psa_cipher_set_iv(&ctx, nonce, sizeof(nonce)); memset(plaintext, 0x3A, SZ); memset(decryptedtext, 0x0, SZ); // Encrypt - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, SZ, nonce, plaintext, ciphertext); + size_t enc_len = 0; + psa_cipher_update(&ctx, plaintext, SZ, ciphertext, SZ, &enc_len); + psa_cipher_finish(&ctx, ciphertext + enc_len, SZ - enc_len, &enc_len); TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - 32, 32); // Decrypt memcpy(nonce, iv, 16); - mbedtls_aes_setkey_dec(&ctx, key_256, 256); - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, SZ, nonce, ciphertext, decryptedtext); + psa_cipher_decrypt_setup(&ctx, key_id, PSA_ALG_CBC_NO_PADDING); + psa_cipher_set_iv(&ctx, nonce, sizeof(nonce)); + psa_cipher_update(&ctx, ciphertext, SZ, decryptedtext, SZ, &enc_len); + psa_cipher_finish(&ctx, decryptedtext + enc_len, SZ - enc_len, &enc_len); TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); - mbedtls_aes_free(&ctx); + psa_cipher_abort(&ctx); free(plaintext); free(ciphertext); free(decryptedtext); diff --git a/components/mbedtls/test_apps/main/test_aes_sha_rsa.c b/components/mbedtls/test_apps/main/test_aes_sha_rsa.c index 650d7b78820..8714ab7dfb0 100644 --- a/components/mbedtls/test_apps/main/test_aes_sha_rsa.c +++ b/components/mbedtls/test_apps/main/test_aes_sha_rsa.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,7 +9,7 @@ #include #if CONFIG_IDF_TARGET_ESP32 - +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "esp_types.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -23,8 +23,7 @@ #include "esp_log.h" #include "sha/sha_parallel_engine.h" #include "aes/esp_aes.h" -#include "mbedtls/rsa.h" -#include "mbedtls/sha256.h" +#include "psa/crypto.h" static const char *TAG = "test"; static volatile bool exit_flag = false; @@ -75,27 +74,33 @@ static void mbedtls_sha256_task(void *pvParameters) SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters; ESP_LOGI(TAG, "mbedtls_sha256_task is started"); const char *input = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz~DEL0123456789Space!#$%&()*+,-.0123456789:;<=>?"; - mbedtls_sha256_context sha256_ctx; unsigned char output[32]; unsigned char output_origin[32]; - mbedtls_sha256_init(&sha256_ctx); + psa_hash_operation_t sha256_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&sha256_op, PSA_ALG_SHA_256); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); memset(output, 0, sizeof(output)); - mbedtls_sha256_starts(&sha256_ctx, false); for (int i = 0; i < 3; ++i) { - mbedtls_sha256_update(&sha256_ctx, (unsigned char *)input, 100); + status = psa_hash_update(&sha256_op, (const uint8_t *)input, 100); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); } - mbedtls_sha256_finish(&sha256_ctx, output); + size_t hash_length = 0; + status = psa_hash_finish(&sha256_op, output, sizeof(output), &hash_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); memcpy(output_origin, output, sizeof(output)); while (exit_flag == false) { - mbedtls_sha256_init(&sha256_ctx); + psa_hash_operation_t sha256_operation = PSA_HASH_OPERATION_INIT; + status = psa_hash_setup(&sha256_operation, PSA_ALG_SHA_256); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); memset(output, 0, sizeof(output)); - mbedtls_sha256_starts(&sha256_ctx, false); for (int i = 0; i < 3; ++i) { - mbedtls_sha256_update(&sha256_ctx, (unsigned char *)input, 100); + status = psa_hash_update(&sha256_operation, (const uint8_t *)input, 100); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); } - mbedtls_sha256_finish(&sha256_ctx, output); + status = psa_hash_finish(&sha256_operation, output, sizeof(output), &hash_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(output, output_origin, sizeof(output), "MBEDTLS SHA256 must match"); } @@ -147,7 +152,6 @@ static void rsa_task(void *pvParameters) SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters; ESP_LOGI(TAG, "rsa_task is started"); while (exit_flag == false) { - mbedtls_rsa_self_test(0); } xSemaphoreGive(*sema); vTaskDelete(NULL); diff --git a/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c b/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c index 2ea61fa5fcb..116515c5307 100644 --- a/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c +++ b/components/mbedtls/test_apps/main/test_ds_sign_and_decrypt.c @@ -6,7 +6,7 @@ #include #include "unity.h" -#include "mbedtls/rsa.h" +#include "mbedtls/private/rsa.h" #include "esp_random.h" #include "sdkconfig.h" @@ -38,9 +38,12 @@ TEST_CASE("ds sign test pkcs1_v15", "[ds_rsa]") mbedtls_esp_random(NULL, hash, sizeof(hash)); // Fill hash with random data unsigned int hashlen = sizeof(hash); unsigned char signature[256] = {0}; + mbedtls_pk_context pk; + mbedtls_pk_init(&pk); + pk.MBEDTLS_PRIVATE(pk_ctx) = &rsa_ctx; // esp_ds is not initialized, so we expect an error - int err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); + int err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); TEST_ASSERT_EQUAL(-1, err); // Initialize the esp_ds context @@ -55,7 +58,7 @@ TEST_CASE("ds sign test pkcs1_v15", "[ds_rsa]") TEST_ASSERT_EQUAL(ESP_OK, err); // Now we can call esp_ds_rsa_sign again - err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); + err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); TEST_ASSERT_EQUAL(0, err); TEST_ASSERT_NOT_NULL(signature); @@ -89,9 +92,12 @@ TEST_CASE("ds sign test pkcs1_v21", "[ds_rsa]") mbedtls_esp_random(NULL, hash, sizeof(hash)); // Fill hash with random data unsigned int hashlen = sizeof(hash); unsigned char signature[256] = {0}; + mbedtls_pk_context pk; + mbedtls_pk_init(&pk); + pk.MBEDTLS_PRIVATE(pk_ctx) = &rsa_ctx; // esp_ds is not initialized, so we expect an error - int err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); + int err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); TEST_ASSERT_EQUAL(-1, err); // Initialize the esp_ds context @@ -106,7 +112,7 @@ TEST_CASE("ds sign test pkcs1_v21", "[ds_rsa]") TEST_ASSERT_EQUAL(ESP_OK, err); // Now we can call esp_ds_rsa_sign again - err = esp_ds_rsa_sign(&rsa_ctx, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); + err = esp_ds_rsa_sign(&pk, mbedtls_esp_random, NULL, MBEDTLS_MD_SHA256, hashlen, hash, signature); TEST_ASSERT_EQUAL(0, err); TEST_ASSERT_NOT_NULL(signature); diff --git a/components/mbedtls/test_apps/main/test_ecp.c b/components/mbedtls/test_apps/main/test_ecp.c index a03005a43d0..dc514efcdde 100644 --- a/components/mbedtls/test_apps/main/test_ecp.c +++ b/components/mbedtls/test_apps/main/test_ecp.c @@ -12,12 +12,12 @@ #include #include #include - -#include -#include -#include -#include +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include +#include #include +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" #include "test_utils.h" #include "ccomp_timer.h" @@ -54,24 +54,20 @@ TEST_CASE("mbedtls ECDH Generate Key", "[mbedtls]") { - mbedtls_ecdh_context ctx; - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; + psa_key_attributes_t key_attributes; + psa_key_id_t key_id; - mbedtls_ecdh_init(&ctx); - mbedtls_ctr_drbg_init(&ctr_drbg); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_bits(&key_attributes, 255); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - mbedtls_entropy_init(&entropy); - TEST_ASSERT_MBEDTLS_OK( mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) ); + psa_status_t status = psa_generate_key(&key_attributes, &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); - TEST_ASSERT_MBEDTLS_OK( mbedtls_ecp_group_load(ACCESS_ECDH(&ctx, grp), MBEDTLS_ECP_DP_CURVE25519) ); - - TEST_ASSERT_MBEDTLS_OK( mbedtls_ecdh_gen_public(ACCESS_ECDH(&ctx, grp), ACCESS_ECDH(&ctx, d), ACCESS_ECDH(&ctx, Q), - mbedtls_ctr_drbg_random, &ctr_drbg ) ); - - mbedtls_ecdh_free(&ctx); - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); + psa_reset_key_attributes(&key_attributes); + psa_destroy_key(key_id); } TEST_CASE("mbedtls ECP self-tests", "[mbedtls]") @@ -82,29 +78,19 @@ TEST_CASE("mbedtls ECP self-tests", "[mbedtls]") TEST_CASE("mbedtls ECP mul w/ koblitz", "[mbedtls]") { /* Test case code via https://github.com/espressif/esp-idf/issues/1556 */ - mbedtls_entropy_context ctxEntropy; - mbedtls_ctr_drbg_context ctxRandom; mbedtls_ecdsa_context ctxECDSA; - const char* pers = "myecdsa"; - - mbedtls_entropy_init(&ctxEntropy); - mbedtls_ctr_drbg_init(&ctxRandom); - TEST_ASSERT_MBEDTLS_OK( mbedtls_ctr_drbg_seed(&ctxRandom, mbedtls_entropy_func, &ctxEntropy, - (const unsigned char*) pers, strlen(pers)) ); mbedtls_ecdsa_init(&ctxECDSA); TEST_ASSERT_MBEDTLS_OK( mbedtls_ecdsa_genkey(&ctxECDSA, MBEDTLS_ECP_DP_SECP256K1, - mbedtls_ctr_drbg_random, &ctxRandom) ); + mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE) ); TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_mul(&ctxECDSA.MBEDTLS_PRIVATE(grp), &ctxECDSA.MBEDTLS_PRIVATE(Q), &ctxECDSA.MBEDTLS_PRIVATE(d), &ctxECDSA.MBEDTLS_PRIVATE(grp).G, - mbedtls_ctr_drbg_random, &ctxRandom) ); + mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE) ); mbedtls_ecdsa_free(&ctxECDSA); - mbedtls_ctr_drbg_free(&ctxRandom); - mbedtls_entropy_free(&ctxEntropy); } #if CONFIG_MBEDTLS_HARDWARE_ECC diff --git a/components/mbedtls/test_apps/main/test_esp_crt_bundle.c b/components/mbedtls/test_apps/main/test_esp_crt_bundle.c index 4b4ae1f927b..ca8c918de15 100644 --- a/components/mbedtls/test_apps/main/test_esp_crt_bundle.c +++ b/components/mbedtls/test_apps/main/test_esp_crt_bundle.c @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2019-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2019-2025 Espressif Systems (Shanghai) CO LTD */ #include #include "esp_err.h" @@ -15,9 +15,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" - -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #include "mbedtls/x509.h" #include "mbedtls/ssl.h" #include "entropy_poll.h" @@ -29,6 +26,8 @@ #include "esp_crt_bundle.h" #include "esp_random.h" +#include "psa/crypto.h" + #include "unity.h" #include "test_utils.h" #include "unity_test_utils.h" @@ -55,15 +54,21 @@ extern const uint8_t wrong_sig_crt_pem_end[] asm("_binary_wrong_sig_crt_esp32_ extern const uint8_t correct_sig_crt_pem_start[] asm("_binary_correct_sig_crt_esp32_com_pem_start"); extern const uint8_t correct_sig_crt_pem_end[] asm("_binary_correct_sig_crt_esp32_com_pem_end"); +// ECDSA test certificates +extern const uint8_t ecdsa_correct_sig_crt_pem_start[] asm("_binary_ecdsa_correct_sig_crt_pem_start"); +extern const uint8_t ecdsa_correct_sig_crt_pem_end[] asm("_binary_ecdsa_correct_sig_crt_pem_end"); + +extern const uint8_t ecdsa_wrong_sig_crt_pem_start[] asm("_binary_ecdsa_wrong_sig_crt_pem_start"); +extern const uint8_t ecdsa_wrong_sig_crt_pem_end[] asm("_binary_ecdsa_wrong_sig_crt_pem_end"); + +extern const uint8_t ecdsa_cert_bundle_start[] asm("_binary_ecdsa_cert_bundle_start"); +extern const uint8_t ecdsa_cert_bundle_end[] asm("_binary_ecdsa_cert_bundle_end"); + #define SEM_TIMEOUT 10000 typedef struct { mbedtls_ssl_context ssl; mbedtls_net_context listen_fd; mbedtls_net_context client_fd; - - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; - mbedtls_ssl_config conf; mbedtls_x509_crt cert; mbedtls_pk_context pkey; @@ -84,12 +89,6 @@ static volatile bool exit_flag; esp_err_t endpoint_teardown(mbedtls_endpoint_t *endpoint); -static int myrand(void *rng_state, unsigned char *output, size_t len) -{ - size_t olen; - return mbedtls_hardware_poll(rng_state, output, len, &olen); -} - esp_err_t server_setup(mbedtls_endpoint_t *server) { int ret; @@ -102,8 +101,6 @@ esp_err_t server_setup(mbedtls_endpoint_t *server) mbedtls_ssl_init( &server->ssl ); mbedtls_x509_crt_init( &server->cert ); mbedtls_pk_init( &server->pkey ); - mbedtls_entropy_init( &server->entropy ); - mbedtls_ctr_drbg_init( &server->ctr_drbg ); ESP_LOGI(TAG, "Loading the server cert and key"); ret = mbedtls_x509_crt_parse( &server->cert, server_cert_chain_pem_start, @@ -115,7 +112,7 @@ esp_err_t server_setup(mbedtls_endpoint_t *server) } ret = mbedtls_pk_parse_key( &server->pkey, (const unsigned char *)server_pk_start, - server_pk_end - server_pk_start, NULL, 0, myrand, NULL ); + server_pk_end - server_pk_start, NULL, 0); if ( ret != 0 ) { ESP_LOGE(TAG, "mbedtls_pk_parse_key returned %d", ret ); return ESP_FAIL; @@ -128,13 +125,6 @@ esp_err_t server_setup(mbedtls_endpoint_t *server) } mbedtls_net_set_nonblock(&server->listen_fd); - ESP_LOGI(TAG, "Seeding the random number generator"); - if ( ( ret = mbedtls_ctr_drbg_seed( &server->ctr_drbg, mbedtls_entropy_func, &server->entropy, - NULL, 0) ) != 0 ) { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned %d", ret ); - return ESP_FAIL; - } - ESP_LOGI(TAG, "Setting up the SSL data"); if ( ( ret = mbedtls_ssl_config_defaults( &server->conf, MBEDTLS_SSL_IS_SERVER, @@ -144,8 +134,6 @@ esp_err_t server_setup(mbedtls_endpoint_t *server) return ESP_FAIL; } - mbedtls_ssl_conf_rng( &server->conf, mbedtls_ctr_drbg_random, &server->ctr_drbg ); - if (( ret = mbedtls_ssl_conf_own_cert( &server->conf, &server->cert, &server->pkey ) ) != 0 ) { ESP_LOGE(TAG, "mbedtls_ssl_conf_own_cert returned %d", ret ); return ESP_FAIL; @@ -209,9 +197,6 @@ esp_err_t endpoint_teardown(mbedtls_endpoint_t *endpoint) mbedtls_ssl_free( &endpoint->ssl ); mbedtls_ssl_config_free( &endpoint->conf ); - mbedtls_ctr_drbg_free( &endpoint->ctr_drbg ); - mbedtls_entropy_free( &endpoint->entropy ); - return ESP_OK; } @@ -223,19 +208,10 @@ esp_err_t client_setup(mbedtls_endpoint_t *client) mbedtls_esp_enable_debug_log( &client->conf, CONFIG_MBEDTLS_DEBUG_LEVEL ); #endif mbedtls_net_init( &client->client_fd ); + mbedtls_net_init( &client->listen_fd ); mbedtls_ssl_init( &client->ssl ); mbedtls_x509_crt_init( &client->cert ); mbedtls_pk_init( &client->pkey ); - mbedtls_entropy_init( &client->entropy ); - mbedtls_ctr_drbg_init( &client->ctr_drbg ); - - ESP_LOGI(TAG, "Seeding the random number generator"); - if ((ret = mbedtls_ctr_drbg_seed(&client->ctr_drbg, mbedtls_entropy_func, &client->entropy, - NULL, 0)) != 0) { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned %d", ret); - return ESP_FAIL; - } - ESP_LOGI(TAG, "Setting hostname for TLS session..."); /* Hostname set here should match CN in server certificate */ if ((ret = mbedtls_ssl_set_hostname(&client->ssl, SERVER_ADDRESS)) != 0) { @@ -251,7 +227,6 @@ esp_err_t client_setup(mbedtls_endpoint_t *client) ESP_LOGE(TAG, "mbedtls_ssl_config_defaults returned %d", ret); return ESP_FAIL; } - mbedtls_ssl_conf_rng(&client->conf, mbedtls_ctr_drbg_random, &client->ctr_drbg); if ((ret = mbedtls_ssl_setup(&client->ssl, &client->conf)) != 0) { ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%x", -ret); @@ -266,26 +241,26 @@ void client_task(void *pvParameters) SemaphoreHandle_t *client_signal_sem = (SemaphoreHandle_t *) pvParameters; int ret = ESP_FAIL; - mbedtls_endpoint_t client; + mbedtls_endpoint_t *client = calloc(1, sizeof(mbedtls_endpoint_t)); esp_crt_validate_res_t res = ESP_CRT_VALIDATE_UNKNOWN; - if (client_setup(&client) != ESP_OK) { + if (client_setup(client) != ESP_OK) { ESP_LOGE(TAG, "SSL client setup failed"); goto exit; } /* Test with default crt bundle that does not contain the ca crt */ ESP_LOGI(TAG, "Connecting to %s:%s...", SERVER_ADDRESS, SERVER_PORT); - if ((ret = mbedtls_net_connect(&client.client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) { + if ((ret = mbedtls_net_connect(&client->client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) { ESP_LOGE(TAG, "mbedtls_net_connect returned -%x", -ret); goto exit; } ESP_LOGI(TAG, "Connected."); - mbedtls_ssl_set_bio(&client.ssl, &client.client_fd, mbedtls_net_send, mbedtls_net_recv, NULL); + mbedtls_ssl_set_bio(&client->ssl, &client->client_fd, mbedtls_net_send, mbedtls_net_recv, NULL); ESP_LOGI(TAG, "Performing the SSL/TLS handshake with bundle that is missing the server root certificate"); - while ( ( ret = mbedtls_ssl_handshake( &client.ssl ) ) != 0 ) { + while ( ( ret = mbedtls_ssl_handshake( &client->ssl ) ) != 0 ) { if ( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) { printf( "mbedtls_ssl_handshake failed with -0x%x\n", -ret ); break; @@ -293,7 +268,7 @@ void client_task(void *pvParameters) } ESP_LOGI(TAG, "Verifying peer X.509 certificate for bundle ..."); - ret = mbedtls_ssl_get_verify_result(&client.ssl); + ret = mbedtls_ssl_get_verify_result(&client->ssl); res = (ret == 0) ? ESP_CRT_VALIDATE_OK : ESP_CRT_VALIDATE_FAIL; @@ -305,25 +280,30 @@ void client_task(void *pvParameters) TEST_ASSERT_EQUAL(ESP_CRT_VALIDATE_FAIL, res); // Reset session before new connection - mbedtls_ssl_close_notify(&client.ssl); - mbedtls_ssl_session_reset(&client.ssl); - mbedtls_net_free( &client.client_fd); + mbedtls_ssl_close_notify(&client->ssl); + mbedtls_ssl_session_reset(&client->ssl); + mbedtls_net_free( &client->client_fd); /* Test with bundle that does contain the CA crt */ - esp_crt_bundle_attach(&client.conf); - esp_crt_bundle_set(server_cert_bundle_start, server_cert_bundle_end - server_cert_bundle_start); + ret = esp_crt_bundle_attach(&client->conf); + TEST_ASSERT_EQUAL(ESP_OK, ret); + + ret = esp_crt_bundle_set(server_cert_bundle_start, server_cert_bundle_end - server_cert_bundle_start); + TEST_ASSERT_EQUAL(ESP_OK, ret); ESP_LOGI(TAG, "Connecting to %s:%s...", SERVER_ADDRESS, SERVER_PORT); - if ((ret = mbedtls_net_connect(&client.client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) { + if ((ret = mbedtls_net_connect(&client->client_fd, SERVER_ADDRESS, SERVER_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) { ESP_LOGE(TAG, "mbedtls_net_connect returned -%x", -ret); goto exit; } ESP_LOGI(TAG, "Connected."); - mbedtls_ssl_set_bio(&client.ssl, &client.client_fd, mbedtls_net_send, mbedtls_net_recv, NULL); + mbedtls_ssl_set_bio(&client->ssl, &client->client_fd, mbedtls_net_send, mbedtls_net_recv, NULL); + size_t available_before_handshake = uxTaskGetStackHighWaterMark(NULL); + ESP_LOGI(TAG, "Available stack before handshake: %d", available_before_handshake); ESP_LOGI(TAG, "Performing the SSL/TLS handshake with bundle that is missing the server root certificate"); - while ( ( ret = mbedtls_ssl_handshake( &client.ssl ) ) != 0 ) { + while ( ( ret = mbedtls_ssl_handshake( &client->ssl ) ) != 0 ) { if ( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) { printf( "mbedtls_ssl_handshake failed with -0x%x\n", -ret ); break; @@ -331,7 +311,7 @@ void client_task(void *pvParameters) } ESP_LOGI(TAG, "Verifying peer X.509 certificate for bundle ..."); - ret = mbedtls_ssl_get_verify_result(&client.ssl); + ret = mbedtls_ssl_get_verify_result(&client->ssl); res = (ret == 0) ? ESP_CRT_VALIDATE_OK : ESP_CRT_VALIDATE_FAIL; @@ -343,17 +323,18 @@ void client_task(void *pvParameters) TEST_ASSERT_EQUAL(ESP_CRT_VALIDATE_OK, res); // Reset session before new connection - mbedtls_ssl_close_notify(&client.ssl); - mbedtls_ssl_session_reset(&client.ssl); - mbedtls_net_free( &client.client_fd); + mbedtls_ssl_close_notify(&client->ssl); + mbedtls_ssl_session_reset(&client->ssl); + mbedtls_net_free( &client->client_fd); exit: - mbedtls_ssl_close_notify(&client.ssl); - mbedtls_ssl_session_reset(&client.ssl); - esp_crt_bundle_detach(&client.conf); - endpoint_teardown(&client); + mbedtls_ssl_close_notify(&client->ssl); + mbedtls_ssl_session_reset(&client->ssl); + esp_crt_bundle_detach(&client->conf); + endpoint_teardown(client); xSemaphoreGive(*client_signal_sem); + free(client); vTaskSuspend(NULL); } @@ -441,6 +422,48 @@ TEST_CASE("custom certificate bundle - wrong signature", "[mbedtls]") esp_crt_bundle_detach(NULL); } +TEST_CASE("custom certificate bundle - ECDSA signature verification", "[mbedtls]") +{ + /* Verify that ECDSA certificates with SHA-512 work correctly with PSA-based verification. + * This tests both the ECDSA algorithm path and a different hash algorithm (SHA-512) than + * the RSA tests which use SHA-256. */ + + mbedtls_x509_crt crt; + uint32_t flags = 0; + + esp_crt_bundle_attach(NULL); + + // Set the ECDSA bundle + esp_crt_bundle_set(ecdsa_cert_bundle_start, ecdsa_cert_bundle_end - ecdsa_cert_bundle_start); + + // Test: ECDSA certificate with wrong signature should FAIL + mbedtls_x509_crt_init(&crt); + printf("Testing ECDSA certificate with wrong signature\n"); + mbedtls_x509_crt_parse(&crt, ecdsa_wrong_sig_crt_pem_start, + ecdsa_wrong_sig_crt_pem_end - ecdsa_wrong_sig_crt_pem_start); + + // Verify with the ECDSA bundle - this should fail + int verify_result = mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags, + esp_crt_verify_callback, NULL); + TEST_ASSERT_NOT_EQUAL(0, verify_result); + mbedtls_x509_crt_free(&crt); + + // Test: ECDSA certificate with correct signature should PASS + mbedtls_x509_crt_init(&crt); + printf("Testing ECDSA certificate with correct signature\n"); + mbedtls_x509_crt_parse(&crt, ecdsa_correct_sig_crt_pem_start, + ecdsa_correct_sig_crt_pem_end - ecdsa_correct_sig_crt_pem_start); + + // Verify with the ECDSA bundle - this should succeed + verify_result = mbedtls_x509_crt_verify(&crt, NULL, NULL, NULL, &flags, + esp_crt_verify_callback, NULL); + + TEST_ASSERT_EQUAL(0, verify_result); + mbedtls_x509_crt_free(&crt); + + esp_crt_bundle_detach(NULL); +} + TEST_CASE("custom certificate bundle init API - bound checking - NULL certificate bundle", "[mbedtls]") { esp_err_t esp_ret; diff --git a/components/mbedtls/test_apps/main/test_gcm.c b/components/mbedtls/test_apps/main/test_gcm.c index 07af880d9ce..b7e86866a5e 100644 --- a/components/mbedtls/test_apps/main/test_gcm.c +++ b/components/mbedtls/test_apps/main/test_gcm.c @@ -6,8 +6,10 @@ #include #include #include "sys/param.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "esp_heap_caps.h" #include "mbedtls/gcm.h" +#include "mbedtls/private/gcm.h" #include "sdkconfig.h" #include "unity.h" diff --git a/components/mbedtls/test_apps/main/test_mbedtls.c b/components/mbedtls/test_apps/main/test_mbedtls.c index a35ba2140b3..1d26a418efd 100644 --- a/components/mbedtls/test_apps/main/test_mbedtls.c +++ b/components/mbedtls/test_apps/main/test_mbedtls.c @@ -14,12 +14,9 @@ #include #include #include -#include "mbedtls/sha1.h" -#include "mbedtls/sha256.h" -#include "mbedtls/sha512.h" -#include "mbedtls/aes.h" -#include "mbedtls/bignum.h" -#include "mbedtls/rsa.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include "mbedtls/private/aes.h" +#include "mbedtls/private/rsa.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" diff --git a/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c b/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c index 7007f3baadb..241f4d97a17 100644 --- a/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c +++ b/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c @@ -9,12 +9,12 @@ #include #include #include - -#include -#include -#include -#include +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include +#include +#include #include +#include "psa/crypto.h" #include "hal/efuse_ll.h" #include "esp_efuse.h" @@ -194,6 +194,31 @@ void test_ecdsa_verify(mbedtls_ecp_group_id id, const uint8_t *hash, const uint8 TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pub_y, plen)); TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1)); + psa_key_id_t key_id; + psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT; + if (id != MBEDTLS_ECP_DP_SECP192R1) { + psa_key_type_t curve_family = PSA_ECC_FAMILY_SECP_R1; + psa_set_key_type(&key_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve_family)); + if (id == MBEDTLS_ECP_DP_SECP256R1) { + psa_set_key_bits(&key_attr, 256); + } + #if SOC_ECDSA_SUPPORT_CURVE_P384 + else if (id == MBEDTLS_ECP_DP_SECP384R1) { + psa_set_key_bits(&key_attr, 384); + } + #endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */ + psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + + uint8_t psa_key[2 * plen + 1]; + psa_key[0] = 0x04; // Uncompressed point indicator + memcpy(&psa_key[1], pub_x, plen); + memcpy(&psa_key[1 + plen], pub_y, plen); + + psa_status_t status = psa_import_key(&key_attr, psa_key, sizeof(psa_key), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + } + if (id == MBEDTLS_ECP_DP_SECP192R1 || id == MBEDTLS_ECP_DP_SECP256R1) { hash_len = HASH_LEN; } @@ -218,6 +243,31 @@ void test_ecdsa_verify(mbedtls_ecp_group_id id, const uint8_t *hash, const uint8 } #endif + if (id != MBEDTLS_ECP_DP_SECP192R1) { + uint8_t signature[2 * plen]; + TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&r, signature, plen)); + TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&s, signature + plen, plen)); + + ccomp_timer_start(); + psa_status_t status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, hash_len, + signature, sizeof(signature)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + elapsed_time = ccomp_timer_stop(); + + if (id == MBEDTLS_ECP_DP_SECP192R1) { + TEST_PERFORMANCE_CCOMP_LESS_THAN(ECDSA_P192_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); + } else if (id == MBEDTLS_ECP_DP_SECP256R1) { + TEST_PERFORMANCE_CCOMP_LESS_THAN(ECDSA_P256_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); + } + #if SOC_ECDSA_SUPPORT_CURVE_P384 + else if (id == MBEDTLS_ECP_DP_SECP384R1) { + TEST_PERFORMANCE_CCOMP_LESS_THAN(ECDSA_P384_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); + } + #endif + psa_destroy_key(key_id); + psa_reset_key_attributes(&key_attr); + } + mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); mbedtls_ecdsa_free(&ecdsa_context); @@ -504,8 +554,8 @@ void test_ecdsa_export_pubkey(mbedtls_ecp_group_id id, const uint8_t *pub_x, con TEST_ASSERT_EQUAL_HEX8_ARRAY(pub_x, export_pub_x, len); TEST_ASSERT_EQUAL_HEX8_ARRAY(pub_y, export_pub_y, len); - mbedtls_ecdsa_free(keypair); - mbedtls_pk_free(&key_ctx); + /* Use esp_ecdsa_free_pk_context instead of manual cleanup to avoid memory leak */ + esp_ecdsa_free_pk_context(&key_ctx); } TEST_CASE("mbedtls ECDSA export public key on SECP192R1", "[mbedtls][efuse_key]") diff --git a/components/mbedtls/test_apps/main/test_mbedtls_mpi.c b/components/mbedtls/test_apps/main/test_mbedtls_mpi.c index 6b1ca3b8dd8..0a963eda4f4 100644 --- a/components/mbedtls/test_apps/main/test_mbedtls_mpi.c +++ b/components/mbedtls/test_apps/main/test_mbedtls_mpi.c @@ -9,6 +9,7 @@ #include #include #include +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "mbedtls/bignum.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" diff --git a/components/mbedtls/test_apps/main/test_mbedtls_sha.c b/components/mbedtls/test_apps/main/test_mbedtls_sha.c deleted file mode 100644 index b17c84e46c9..00000000000 --- a/components/mbedtls/test_apps/main/test_mbedtls_sha.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * mbedTLS SHA unit tests - */ -#include -#include -#include -#include -#include "mbedtls/sha1.h" -#include "mbedtls/sha256.h" -#include "mbedtls/sha512.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "unity.h" -#include "sdkconfig.h" -#include "test_apb_dport_access.h" -#include "soc/soc_caps.h" -#include "test_utils.h" -#include "esp_memory_utils.h" - -TEST_CASE("mbedtls SHA self-tests", "[mbedtls]") -{ - start_apb_access_loop(); -#if CONFIG_MBEDTLS_SHA1_C - TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass."); -#endif - TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha256_self_test(1), "SHA256 self-tests should pass."); -#if CONFIG_MBEDTLS_SHA512_C - TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass."); -#endif - verify_apb_access_loop(); -} - -static const unsigned char *one_hundred_as = (unsigned char *) - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - -static const unsigned char *one_hundred_bs = (unsigned char *) - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; - -static const uint8_t sha256_thousand_as[32] = { - 0x41, 0xed, 0xec, 0xe4, 0x2d, 0x63, 0xe8, 0xd9, 0xbf, 0x51, 0x5a, 0x9b, 0xa6, 0x93, 0x2e, 0x1c, - 0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64, 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3 -}; - - -static const uint8_t sha256_thousand_bs[32] = { - 0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b -}; - -static const uint8_t sha512_thousand_bs[64] = { - 0xa6, 0x68, 0x68, 0xa3, 0x73, 0x53, 0x2a, 0x5c, 0xc3, 0x3f, 0xbf, 0x43, 0x4e, 0xba, 0x10, 0x86, 0xb3, 0x87, 0x09, 0xe9, 0x14, 0x3f, 0xbf, 0x37, 0x67, 0x8d, 0x43, 0xd9, 0x9b, 0x95, 0x08, 0xd5, 0x80, 0x2d, 0xbe, 0x9d, 0xe9, 0x1a, 0x54, 0xab, 0x9e, 0xbc, 0x8a, 0x08, 0xa0, 0x1a, 0x89, 0xd8, 0x72, 0x68, 0xdf, 0x52, 0x69, 0x7f, 0x1c, 0x70, 0xda, 0xe8, 0x3f, 0xe5, 0xae, 0x5a, 0xfc, 0x9d -}; - -static const uint8_t sha384_thousand_bs[48] = { - 0x6d, 0xe5, 0xf5, 0x88, 0x57, 0x60, 0x83, 0xff, 0x7c, 0x94, 0x61, 0x5f, 0x8d, 0x96, 0xf2, 0x76, 0xd5, 0x3f, 0x77, 0x0c, 0x8e, 0xc1, 0xbf, 0xb6, 0x04, 0x27, 0xa4, 0xba, 0xea, 0x6c, 0x68, 0x44, 0xbd, 0xb0, 0x9c, 0xef, 0x6a, 0x09, 0x28, 0xe8, 0x1f, 0xfc, 0x95, 0x03, 0x69, 0x99, 0xab, 0x1a -}; - -static const uint8_t sha1_thousand_as[20] = { - 0x29, 0x1e, 0x9a, 0x6c, 0x66, 0x99, 0x49, 0x49, 0xb5, 0x7b, 0xa5, - 0xe6, 0x50, 0x36, 0x1e, 0x98, 0xfc, 0x36, 0xb1, 0xba -}; - - -TEST_CASE("mbedtls SHA interleaving", "[mbedtls]") -{ - mbedtls_sha1_context sha1_ctx; - mbedtls_sha256_context sha256_ctx; - mbedtls_sha512_context sha512_ctx; - unsigned char sha1[20], sha256[32], sha512[64]; - - mbedtls_sha1_init(&sha1_ctx); - mbedtls_sha256_init(&sha256_ctx); - mbedtls_sha512_init(&sha512_ctx); - - TEST_ASSERT_EQUAL(0, mbedtls_sha1_starts(&sha1_ctx)); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false)); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts(&sha512_ctx, false)); - - for (int i = 0; i < 10; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha1_update(&sha1_ctx, one_hundred_as, 100)); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, one_hundred_as, 100)); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&sha512_ctx, one_hundred_bs, 100)); - } - - TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish(&sha1_ctx, sha1)); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256)); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&sha512_ctx, sha512)); - - mbedtls_sha1_free(&sha1_ctx); - mbedtls_sha256_free(&sha256_ctx); - mbedtls_sha512_free(&sha512_ctx); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 calculation"); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 calculation"); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation"); -} - -#define SHA_TASK_STACK_SIZE (10*1024) -static SemaphoreHandle_t done_sem; - -static void tskRunSHA1Test(void *pvParameters) -{ - mbedtls_sha1_context sha1_ctx; - unsigned char sha1[20]; - - for (int i = 0; i < 1000; i++) { - mbedtls_sha1_init(&sha1_ctx); - TEST_ASSERT_EQUAL(0, mbedtls_sha1_starts(&sha1_ctx)); - for (int j = 0; j < 10; j++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha1_update(&sha1_ctx, (unsigned char *)one_hundred_as, 100)); - } - TEST_ASSERT_EQUAL(0, mbedtls_sha1_finish(&sha1_ctx, sha1)); - mbedtls_sha1_free(&sha1_ctx); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation"); - } - xSemaphoreGive(done_sem); - vTaskDelete(NULL); -} - -static void tskRunSHA256Test(void *pvParameters) -{ - mbedtls_sha256_context sha256_ctx; - unsigned char sha256[32]; - - for (int i = 0; i < 1000; i++) { - mbedtls_sha256_init(&sha256_ctx); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false)); - for (int j = 0; j < 10; j++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, (unsigned char *)one_hundred_bs, 100)); - } - TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256)); - mbedtls_sha256_free(&sha256_ctx); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation"); - } - xSemaphoreGive(done_sem); - vTaskDelete(NULL); -} - - -TEST_CASE("mbedtls SHA multithreading", "[mbedtls]") -{ - done_sem = xSemaphoreCreateCounting(4, 0); - xTaskCreate(tskRunSHA1Test, "SHA1Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL); - xTaskCreate(tskRunSHA1Test, "SHA1Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL); - xTaskCreate(tskRunSHA256Test, "SHA256Task1", SHA_TASK_STACK_SIZE, NULL, 3, NULL); - xTaskCreate(tskRunSHA256Test, "SHA256Task2", SHA_TASK_STACK_SIZE, NULL, 3, NULL); - - for (int i = 0; i < 4; i++) { - if (!xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)) { - TEST_FAIL_MESSAGE("done_sem not released by test task"); - } - } - vSemaphoreDelete(done_sem); -} - -void tskRunSHASelftests(void *param) -{ - for (int i = 0; i < 5; i++) { -#if CONFIG_MBEDTLS_SHA1_C - if (mbedtls_sha1_self_test(1)) { - printf("SHA1 self-tests failed.\n"); - while (1) {} - } -#endif - - if (mbedtls_sha256_self_test(1)) { - printf("SHA256 self-tests failed.\n"); - while (1) {} - } - -#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C - if (mbedtls_sha512_self_test(1)) { - printf("SHA512 self-tests failed.\n"); - while (1) {} - } - - if (mbedtls_sha512_self_test(1)) { - printf("SHA512 self-tests failed.\n"); - while (1) {} - } -#endif //SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C - } - xSemaphoreGive(done_sem); - vTaskDelete(NULL); -} - -TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]") -{ - done_sem = xSemaphoreCreateCounting(2, 0); - xTaskCreate(tskRunSHASelftests, "SHASelftests1", SHA_TASK_STACK_SIZE, NULL, 3, NULL); - xTaskCreate(tskRunSHASelftests, "SHASelftests2", SHA_TASK_STACK_SIZE, NULL, 3, NULL); - - const int TIMEOUT_MS = 40000; - - for (int i = 0; i < 2; i++) { - if (!xSemaphoreTake(done_sem, TIMEOUT_MS / portTICK_PERIOD_MS)) { - TEST_FAIL_MESSAGE("done_sem not released by test task"); - } - } - vSemaphoreDelete(done_sem); -} - -TEST_CASE("mbedtls SHA512 clone", "[mbedtls]") -{ - mbedtls_sha512_context ctx; - mbedtls_sha512_context clone; - unsigned char sha512[64]; - - mbedtls_sha512_init(&ctx); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts(&ctx, false)); - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&ctx, one_hundred_bs, 100)); - } - - mbedtls_sha512_init(&clone); - mbedtls_sha512_clone(&clone, &ctx); - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&ctx, one_hundred_bs, 100)); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&clone, one_hundred_bs, 100)); - } - TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&ctx, sha512)); - mbedtls_sha512_free(&ctx); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 original calculation"); - - TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&clone, sha512)); - mbedtls_sha512_free(&clone); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation"); -} - -TEST_CASE("mbedtls SHA384 clone", "[mbedtls]") -{ - mbedtls_sha512_context ctx; - mbedtls_sha512_context clone; - - unsigned char sha384[48]; - - mbedtls_sha512_init(&ctx); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts(&ctx, true)); - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&ctx, one_hundred_bs, 100)); - } - - mbedtls_sha512_init(&clone); - mbedtls_sha512_clone(&clone, &ctx); - - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&ctx, one_hundred_bs, 100)); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&clone, one_hundred_bs, 100)); - } -/* intended warning suppression: is384 == true */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstringop-overflow" - TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&ctx, sha384)); -#pragma GCC diagnostic pop - mbedtls_sha512_free(&ctx); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 original calculation"); - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstringop-overflow" - TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&clone, sha384)); -#pragma GCC diagnostic pop - mbedtls_sha512_free(&clone); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 cloned calculation"); -} - - -TEST_CASE("mbedtls SHA256 clone", "[mbedtls]") -{ - mbedtls_sha256_context ctx; - mbedtls_sha256_context clone; - unsigned char sha256[64]; - - mbedtls_sha256_init(&ctx); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&ctx, false)); - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&ctx, one_hundred_as, 100)); - } - - mbedtls_sha256_init(&clone); - mbedtls_sha256_clone(&clone, &ctx); - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&ctx, one_hundred_as, 100)); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&clone, one_hundred_as, 100)); - } - TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&ctx, sha256)); - mbedtls_sha256_free(&ctx); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 original calculation"); - - TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&clone, sha256)); - mbedtls_sha256_free(&clone); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 cloned calculation"); -} - -typedef struct { - mbedtls_sha256_context ctx; - uint8_t result[32]; - int ret; - bool done; -} finalise_sha_param_t; - -static void tskFinaliseSha(void *v_param) -{ - finalise_sha_param_t *param = (finalise_sha_param_t *)v_param; - - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(¶m->ctx, one_hundred_as, 100)); - } - - param->ret = mbedtls_sha256_finish(¶m->ctx, param->result); - mbedtls_sha256_free(¶m->ctx); - - param->done = true; - vTaskDelete(NULL); -} - - -TEST_CASE("mbedtls SHA session passed between tasks", "[mbedtls]") -{ - finalise_sha_param_t param = { 0 }; - - mbedtls_sha256_init(¶m.ctx); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(¶m.ctx, false)); - for (int i = 0; i < 5; i++) { - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(¶m.ctx, one_hundred_as, 100)); - } - - // pass the SHA context off to a different task - // - // note: at the moment this doesn't crash even if a mutex semaphore is used as the - // engine lock, but it can crash... - xTaskCreate(tskFinaliseSha, "SHAFinalise", SHA_TASK_STACK_SIZE, ¶m, 3, NULL); - - while (!param.done) { - vTaskDelay(1); - } - - TEST_ASSERT_EQUAL(0, param.ret); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, param.result, 32, "SHA256 result from other task"); -} - - - -/* Random input generated and hashed using python: - - import hashlib - import os, binascii - - input = bytearray(os.urandom(150)) - arr = '' - for idx, b in enumerate(input): - if idx % 8 == 0: - arr += '\n' - arr += "{}, ".format(hex(b)) - digest = hashlib.sha256(input).hexdigest() - -*/ -const uint8_t test_vector[] = { - 0xe4, 0x1a, 0x1a, 0x30, 0x71, 0xd3, 0x94, 0xb0, - 0xc3, 0x7e, 0x99, 0x9f, 0x1a, 0xde, 0x4a, 0x36, - 0xb1, 0x1, 0x81, 0x2b, 0x41, 0x91, 0x11, 0x7f, - 0xd8, 0xe1, 0xd5, 0xe5, 0x52, 0x6d, 0x92, 0xee, - 0x6c, 0xf7, 0x70, 0xea, 0x3a, 0xb, 0xc9, 0x97, - 0xc0, 0x12, 0x6f, 0x10, 0x5b, 0x90, 0xd8, 0x52, - 0x91, 0x69, 0xea, 0xc4, 0x1f, 0xc, 0xcf, 0xc6, - 0xf0, 0x43, 0xc6, 0xa3, 0x1f, 0x46, 0x3c, 0x3d, - 0x25, 0xe5, 0xa8, 0x27, 0x86, 0x85, 0x32, 0x3f, - 0x33, 0xd8, 0x40, 0xc4, 0x41, 0xf6, 0x4b, 0x12, - 0xd8, 0x5e, 0x4, 0x27, 0x42, 0x90, 0x73, 0x4, - 0x8, 0x42, 0xd1, 0x64, 0xd, 0x84, 0x3, 0x1, - 0x76, 0x88, 0xe4, 0x95, 0xdf, 0xe7, 0x62, 0xb4, - 0xb3, 0xb2, 0x7e, 0x6d, 0x78, 0xca, 0x79, 0x82, - 0xcc, 0xba, 0x22, 0xd2, 0x90, 0x2e, 0xe3, 0xa8, - 0x2a, 0x53, 0x3a, 0xb1, 0x9a, 0x7f, 0xb7, 0x8b, - 0xfa, 0x32, 0x47, 0xc1, 0x5c, 0x6, 0x4f, 0x7b, - 0xcd, 0xb3, 0xf4, 0xf1, 0xd0, 0xb5, 0xbf, 0xfb, - 0x7c, 0xc3, 0xa5, 0xb2, 0xc4, 0xd4, -}; - -const uint8_t test_vector_digest[] = { - 0xff, 0x1c, 0x60, 0xcb, 0x21, 0xf0, 0x63, 0x68, - 0xb9, 0xfc, 0xfe, 0xad, 0x3e, 0xb0, 0x2e, 0xd1, - 0xf9, 0x08, 0x82, 0x82, 0x83, 0x06, 0xc1, 0x8a, - 0x98, 0x5d, 0x36, 0xc0, 0xb7, 0xeb, 0x35, 0xe0, -}; - - -TEST_CASE("mbedtls SHA, input in flash", "[mbedtls]") -{ - mbedtls_sha256_context sha256_ctx; - unsigned char sha256[32]; - - mbedtls_sha256_init(&sha256_ctx); - - TEST_ASSERT_EQUAL(0, mbedtls_sha256_starts(&sha256_ctx, false)); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_update(&sha256_ctx, test_vector, sizeof(test_vector))); - TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256)); - mbedtls_sha256_free(&sha256_ctx); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(test_vector_digest, sha256, 32, "SHA256 calculation"); -} - -/* Function are not implemented in SW */ -#if CONFIG_MBEDTLS_HARDWARE_SHA && SOC_SHA_SUPPORT_SHA512_T - -/* - * FIPS-180-2 test vectors - */ -static unsigned char sha512T_test_buf[2][113] = { - { "abc" }, - { - "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" - } -}; - -static const size_t sha512T_test_buflen[2] = { - 3, 112 -}; - -static const esp_sha_type sha512T_algo[4] = { - SHA2_512224, SHA2_512256, SHA2_512T, SHA2_512T -}; - -static const size_t sha512T_t_len[4] = { 224, 256, 224, 256 }; - -static const unsigned char sha512_test_sum[4][32] = { - /* SHA512-224 */ - { - 0x46, 0x34, 0x27, 0x0f, 0x70, 0x7b, 0x6a, 0x54, - 0xda, 0xae, 0x75, 0x30, 0x46, 0x08, 0x42, 0xe2, - 0x0e, 0x37, 0xed, 0x26, 0x5c, 0xee, 0xe9, 0xa4, - 0x3e, 0x89, 0x24, 0xaa - }, - { - 0x23, 0xfe, 0xc5, 0xbb, 0x94, 0xd6, 0x0b, 0x23, - 0x30, 0x81, 0x92, 0x64, 0x0b, 0x0c, 0x45, 0x33, - 0x35, 0xd6, 0x64, 0x73, 0x4f, 0xe4, 0x0e, 0x72, - 0x68, 0x67, 0x4a, 0xf9 - }, - - /* SHA512-256 */ - { - 0x53, 0x04, 0x8e, 0x26, 0x81, 0x94, 0x1e, 0xf9, - 0x9b, 0x2e, 0x29, 0xb7, 0x6b, 0x4c, 0x7d, 0xab, - 0xe4, 0xc2, 0xd0, 0xc6, 0x34, 0xfc, 0x6d, 0x46, - 0xe0, 0xe2, 0xf1, 0x31, 0x07, 0xe7, 0xaf, 0x23 - }, - { - 0x39, 0x28, 0xe1, 0x84, 0xfb, 0x86, 0x90, 0xf8, - 0x40, 0xda, 0x39, 0x88, 0x12, 0x1d, 0x31, 0xbe, - 0x65, 0xcb, 0x9d, 0x3e, 0xf8, 0x3e, 0xe6, 0x14, - 0x6f, 0xea, 0xc8, 0x61, 0xe1, 0x9b, 0x56, 0x3a - } - - /* For SHA512_T testing we use t=224 & t=256 - * so the hash digest should be same as above - */ -}; - -/* This will run total of 8 test cases, 2 for each of the below MODE - * SHA512/224, SHA512/256, SHA512/t with t=224 & SHA512/t with t=256 - * - * Test is disabled for ESP32 as there is no hardware for SHA512/t - */ -TEST_CASE("mbedtls SHA512/t", "[mbedtls]") -{ - mbedtls_sha512_context sha512_ctx; - unsigned char sha512[64], k; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 2; j++) { - k = i * 2 + j; - mbedtls_sha512_init(&sha512_ctx); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_starts(&sha512_ctx, false)); - esp_sha512_set_mode(&sha512_ctx, sha512T_algo[i]); - if (i > 1) { - k = (i - 2) * 2 + j; - esp_sha512_set_t(&sha512_ctx, sha512T_t_len[i]); - } - TEST_ASSERT_EQUAL(0, mbedtls_sha512_update(&sha512_ctx, sha512T_test_buf[j], sha512T_test_buflen[j])); - TEST_ASSERT_EQUAL(0, mbedtls_sha512_finish(&sha512_ctx, sha512)); - mbedtls_sha512_free(&sha512_ctx); - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_test_sum[k], sha512, sha512T_t_len[i] / 8, "SHA512t calculation"); - } - } -} -#endif //CONFIG_MBEDTLS_HARDWARE_SHA - -#ifdef CONFIG_SPIRAM_USE_MALLOC -#include "test_mbedtls_utils.h" -TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]") -{ - const unsigned CALLS = 256; - const unsigned CALL_SZ = 16 * 1024; - mbedtls_sha256_context sha256_ctx; - unsigned char sha256[32]; - - // allocate external memory - uint8_t *buf = heap_caps_malloc(CALL_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); - TEST_ASSERT(esp_ptr_external_ram(buf)); - memset(buf, 0x54, CALL_SZ); - - mbedtls_sha256_init(&sha256_ctx); - 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)); - } - TEST_ASSERT_EQUAL(0, mbedtls_sha256_finish(&sha256_ctx, sha256)); - - 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' '\124' | sha256sum - */ - const char *expected_hash = "8d031167bd706ac337e07aa9129c34ae4ae792d0a79a2c70e7f012102e8adc3d"; - char hash_str[sizeof(sha256) * 2 + 1]; - utils_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256)); - - TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str); - -} - -#if SOC_SHA_SUPPORT_DMA -TEST_CASE("mbedtls SHA256 PSRAM DMA large buffer", "[hw_crypto]") -{ - mbedtls_sha256_context sha256_ctx; - unsigned char sha256[32]; - - const size_t SZ = 257984; // specific size to cover issue in https://github.com/espressif/esp-idf/issues/11915 - void *buffer = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); - TEST_ASSERT_NOT_NULL(buffer); - memset(buffer, 0x55, SZ); - - mbedtls_sha256_init(&sha256_ctx); - int r = mbedtls_sha256_starts(&sha256_ctx, false); - TEST_ASSERT_EQUAL(0, r); - r = mbedtls_sha256_update(&sha256_ctx, buffer, SZ); - TEST_ASSERT_EQUAL(0, r); - r = mbedtls_sha256_finish(&sha256_ctx, sha256); - TEST_ASSERT_EQUAL(0, r); - mbedtls_sha256_free(&sha256_ctx); - free(buffer); - - /* Check the result. Reference value can be calculated using: - * dd if=/dev/zero bs=257984 count=1 | tr '\000' '\125' | sha256sum - */ - const char *expected_hash = "f2330c9f81ff1c8f0515247faa82be8b6f9685601de6f5dae79172766f136c33"; - - char hash_str[sizeof(sha256) * 2 + 1]; - utils_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256)); - - TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str); -} -#endif // SOC_SHA_SUPPORT_DMA - -#endif //CONFIG_SPIRAM_USE_MALLOC - -#if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK && !CONFIG_IDF_TARGET_ESP32H2 -// Not enough rtc memory for test on H2 - -TEST_CASE("mbedtls SHA stack in RTC RAM", "[mbedtls]") -{ - done_sem = xSemaphoreCreateBinary(); - static StaticTask_t rtc_task; - size_t STACK_SIZE = 3072; - uint8_t *rtc_stack = heap_caps_calloc(STACK_SIZE, 1, MALLOC_CAP_RTCRAM); - - TEST_ASSERT(esp_ptr_in_rtc_dram_fast(rtc_stack)); - - TEST_ASSERT_NOT_NULL(xTaskCreateStatic(tskRunSHA256Test, "tskRunSHA256Test_task", STACK_SIZE, NULL, - 3, rtc_stack, &rtc_task)); - TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)); - - /* Give task time to cleanup before freeing stack */ - vTaskDelay(1000 / portTICK_PERIOD_MS); - free(rtc_stack); - - vSemaphoreDelete(done_sem); -} - -#endif //CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK - -#if CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM && CONFIG_SPIRAM_USE_MALLOC - -TEST_CASE("mbedtls SHA stack in PSRAM", "[mbedtls]") -{ - done_sem = xSemaphoreCreateBinary(); - static StaticTask_t psram_task; - size_t STACK_SIZE = 3072; - uint8_t *psram_stack = heap_caps_calloc(STACK_SIZE, 1, MALLOC_CAP_SPIRAM); - - TEST_ASSERT(esp_ptr_external_ram(psram_stack)); - - TEST_ASSERT_NOT_NULL(xTaskCreateStatic(tskRunSHA256Test, "tskRunSHA256Test_task", STACK_SIZE, NULL, - 3, psram_stack, &psram_task)); - TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS)); - - /* Give task time to cleanup before freeing stack */ - vTaskDelay(1000 / portTICK_PERIOD_MS); - free(psram_stack); - - vSemaphoreDelete(done_sem); -} - -#endif //CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM && CONFIG_SPIRAM_USE_MALLOC diff --git a/components/mbedtls/test_apps/main/test_psa_aes.c b/components/mbedtls/test_apps/main/test_psa_aes.c new file mode 100644 index 00000000000..b58e78c76ef --- /dev/null +++ b/components/mbedtls/test_apps/main/test_psa_aes.c @@ -0,0 +1,869 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include + +#include "esp_heap_caps.h" +#include "esp_log.h" +#include "esp_private/periph_ctrl.h" + +#include "psa/crypto.h" + +#include "unity.h" + +static const uint8_t key_256[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +}; + +TEST_CASE("PSA AES-CTR multipart", "[psa-aes]") +{ + const size_t SZ = 100; + const size_t iv_SZ = 16; + const size_t part_size = 8; + + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + + TEST_ASSERT_NOT_NULL(plaintext); + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(decryptedtext); + uint8_t iv[iv_SZ]; + + memset(plaintext, 0x3A, SZ); + memset(decryptedtext, 0x0, SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_CTR; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + + psa_reset_key_attributes(&attributes); + + /* Encrypt */ + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len, total_out_len = 0; + + memset(iv, 0x3B, iv_SZ); // Initialize IV with known value + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + /* Decrypt */ + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + total_out_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + free(plaintext); + free(ciphertext); + free(decryptedtext); + + psa_cipher_abort(&enc_op); + psa_cipher_abort(&dec_op); + + /* Destroy the key */ + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-ECB multipart", "[psa-aes]") +{ + const size_t SZ = 112; + const size_t iv_SZ = 16; + const size_t part_size = 16; + + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + + TEST_ASSERT_NOT_NULL(plaintext); + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(decryptedtext); + uint8_t iv[iv_SZ]; + + memset(plaintext, 0x3A, SZ); + memset(decryptedtext, 0x0, SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + + psa_reset_key_attributes(&attributes); + + /* Encrypt */ + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len, total_out_len = 0; + + memset(iv, 0x3B, iv_SZ); // Initialize IV with known value + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg)); + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + /* Decrypt */ + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + total_out_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg)); + + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + free(plaintext); + free(ciphertext); + free(decryptedtext); + + psa_cipher_abort(&enc_op); + psa_cipher_abort(&dec_op); + + /* Destroy the key */ + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-CBC multipart", "[psa-aes]") +{ + const size_t SZ = 112; // Multiple of block size (16) + const size_t iv_SZ = 16; + const size_t part_size = 16; // Process one block at a time + + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + + TEST_ASSERT_NOT_NULL(plaintext); + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(decryptedtext); + uint8_t iv[iv_SZ]; + + memset(plaintext, 0x3A, SZ); + memset(decryptedtext, 0x0, SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + + psa_reset_key_attributes(&attributes); + + /* Encrypt */ + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len, total_out_len = 0; + + memset(iv, 0x3B, iv_SZ); // Initialize IV with known value + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + /* Decrypt */ + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + total_out_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + free(plaintext); + free(ciphertext); + free(decryptedtext); + + psa_cipher_abort(&enc_op); + psa_cipher_abort(&dec_op); + + /* Destroy the key */ + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-CBC-PKCS7 multipart", "[psa-aes]") +{ + // Test both aligned and unaligned sizes + const size_t SZ1 = 112; // Multiple of block size (16) + const size_t SZ2 = 123; // Not a multiple of block size + const size_t iv_SZ = 16; + const size_t part_size = 16; + + uint8_t *plaintext1 = malloc(SZ1); + uint8_t *ciphertext1 = malloc(SZ1 + 16); // Extra block for padding + uint8_t *decryptedtext1 = malloc(SZ1 + 16); // Extra space for intermediate buffering + + uint8_t *plaintext2 = malloc(SZ2); + uint8_t *ciphertext2 = malloc(SZ2 + 16); // Extra block for padding + uint8_t *decryptedtext2 = malloc(SZ2 + 16); // Extra space for intermediate buffering + + uint8_t iv[iv_SZ]; + + // Initialize test data + memset(plaintext1, 0x3A, SZ1); + memset(plaintext2, 0x3B, SZ2); + memset(ciphertext1, 0x0, SZ1 + 16); + memset(ciphertext2, 0x0, SZ2 + 16); + memset(decryptedtext1, 0x0, SZ1 + 16); + memset(decryptedtext2, 0x0, SZ2 + 16); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_CBC_PKCS7; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + + psa_reset_key_attributes(&attributes); + + /* Test 1: Block-aligned input */ + { + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len, total_out_len = 0; + + memset(iv, 0x3C, iv_SZ); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + + // Process all blocks except the last one + for (size_t offset = 0; offset < SZ1 - part_size; offset += part_size) { + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext1 + offset, part_size, + ciphertext1 + total_out_len, SZ1 + 16 - total_out_len, &out_len)); + total_out_len += out_len; + } + + // Process the last block separately + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext1 + SZ1 - part_size, part_size, + ciphertext1 + total_out_len, SZ1 + 16 - total_out_len, &out_len)); + total_out_len += out_len; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext1 + total_out_len, + SZ1 + 16 - total_out_len, &out_len)); // Space for padding block + total_out_len += out_len; + + // The output size should be the input size rounded up to the next multiple of 16 + TEST_ASSERT_EQUAL_size_t((SZ1 + 16), total_out_len); // Should include padding block + /* Decrypt */ + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + size_t dec_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < total_out_len; offset += part_size) { + size_t this_part = total_out_len - offset < part_size ? total_out_len - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext1 + offset, this_part, + decryptedtext1 + dec_len, SZ1 + 16 - dec_len, &out_len)); + dec_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext1 + dec_len, + SZ1 + 16 - dec_len, &out_len)); + dec_len += out_len; + + TEST_ASSERT_EQUAL_size_t(SZ1, dec_len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext1, decryptedtext1, SZ1); + + psa_cipher_abort(&enc_op); + psa_cipher_abort(&dec_op); + } + + /* Test 2: Non-block-aligned input */ + { + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len, total_out_len = 0; + + memset(iv, 0x3D, iv_SZ); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ2; offset += part_size) { + size_t this_part = SZ2 - offset < part_size ? SZ2 - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext2 + offset, this_part, + ciphertext2 + total_out_len, SZ2 + 16 - total_out_len, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext2 + total_out_len, + SZ2 + 16 - total_out_len, &out_len)); + total_out_len += out_len; + + /* Decrypt */ + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + size_t dec_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < total_out_len; offset += part_size) { + size_t this_part = total_out_len - offset < part_size ? total_out_len - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext2 + offset, this_part, + decryptedtext2 + dec_len, SZ2 + 16 - dec_len, &out_len)); + dec_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext2 + dec_len, + SZ2 + 16 - dec_len, &out_len)); + dec_len += out_len; + + TEST_ASSERT_EQUAL_size_t(SZ2, dec_len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext2, decryptedtext2, SZ2); + + psa_cipher_abort(&enc_op); + psa_cipher_abort(&dec_op); + } + + /* Cleanup */ + free(plaintext1); + free(ciphertext1); + free(decryptedtext1); + free(plaintext2); + free(ciphertext2); + free(decryptedtext2); + + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-CFB multipart", "[psa-aes]") +{ + const size_t SZ = 100; + const size_t iv_SZ = 16; + const size_t part_size = 8; + + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + uint8_t iv[iv_SZ]; + + memset(plaintext, 0x3A, SZ); + memset(decryptedtext, 0x0, SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_CFB; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + + psa_reset_key_attributes(&attributes); + + /* Encrypt */ + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len, total_out_len = 0; + + memset(iv, 0x3B, iv_SZ); // Initialize IV with known value + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + /* Decrypt */ + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + total_out_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + free(plaintext); + free(ciphertext); + free(decryptedtext); + + psa_cipher_abort(&enc_op); + psa_cipher_abort(&dec_op); + + /* Destroy the key */ + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-OFB multipart", "[psa-aes]") +{ + const size_t SZ = 100; + const size_t iv_SZ = 16; + const size_t part_size = 8; + + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + uint8_t iv[iv_SZ]; + + memset(plaintext, 0x3A, SZ); + memset(decryptedtext, 0x0, SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_OFB; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + + psa_reset_key_attributes(&attributes); + + /* Encrypt */ + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len, total_out_len = 0; + + memset(iv, 0x3B, iv_SZ); // Initialize IV with known value + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + /* Decrypt */ + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + total_out_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out_len, + SZ - total_out_len, &out_len)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + free(plaintext); + free(ciphertext); + free(decryptedtext); + + psa_cipher_abort(&enc_op); + psa_cipher_abort(&dec_op); + + /* Destroy the key */ + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-CTR streaming chunk invariance", "[psa-aes]") +{ + const size_t SZ = 100; + const size_t iv_SZ = 16; + + // Vectors match legacy mbedtls CTR stream test + const uint8_t expected_cipher[] = { + 0xc5, 0x78, 0xa7, 0xb4, 0xf3, 0xb9, 0xcb, 0x8b, + 0x09, 0xe0, 0xd6, 0x89, 0x14, 0x6a, 0x19, 0x09, + 0xde, 0xaf, 0x37, 0x19, 0x32, 0x4d, 0xca, 0xf6, + 0xff, 0x6e, 0xd2, 0x5d, 0x87, 0x51, 0xaa, 0x8c, + 0x1c, 0xe3, 0x3b, 0xbb, 0x18, 0xf5, 0xa0, 0x1b, + 0xdc, 0x29, 0x52, 0x63, 0xf6, 0x5d, 0x49, 0x85, + 0x29, 0xf1, 0xf0, 0x69, 0x8f, 0xa6, 0x9f, 0x38, + 0x5c, 0xdd, 0x26, 0xf8, 0x9d, 0x40, 0xa1, 0xff, + 0x52, 0x46, 0xe1, 0x72, 0x70, 0x39, 0x73, 0xff, + 0xd0, 0x5e, 0xe5, 0x3f, 0xc5, 0xed, 0x5c, 0x18, + 0xa7, 0x84, 0xd8, 0xdf, 0x9d, 0xb5, 0x06, 0xb1, + 0xa7, 0xcf, 0x2e, 0x7a, 0x51, 0xfc, 0x44, 0xc5, + 0xb9, 0x5f, 0x22, 0x47, + }; + + uint8_t key[16]; + uint8_t iv[iv_SZ]; + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + + memset(key, 0x44, sizeof(key)); + memset(iv, 0xEE, iv_SZ); + memset(plaintext, 0xAA, SZ); + + psa_key_id_t key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CTR); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key, sizeof(key), &key_id)); + psa_reset_key_attributes(&attributes); + + for (size_t chunk = 1; chunk < SZ; chunk++) { + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len = 0, total_out = 0; + + memset(iv, 0xEE, iv_SZ); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, PSA_ALG_CTR)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += chunk) { + size_t this_part = SZ - offset < chunk ? SZ - offset : chunk; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out, + SZ - total_out, &out_len)); + total_out += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ); + + psa_cipher_abort(&enc_op); + + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + total_out = 0; + memset(iv, 0xEE, iv_SZ); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, PSA_ALG_CTR)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += chunk) { + size_t this_part = SZ - offset < chunk ? SZ - offset : chunk; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out, + SZ - total_out, &out_len)); + total_out += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + psa_cipher_abort(&dec_op); + } + + free(plaintext); + free(ciphertext); + free(decryptedtext); + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-OFB streaming chunk invariance", "[psa-aes]") +{ + const size_t SZ = 100; + const size_t iv_SZ = 16; + + // Vectors match legacy mbedtls OFB stream test + const uint8_t expected_cipher[] = { + 0xc5, 0x78, 0xa7, 0xb4, 0xf3, 0xb9, 0xcb, 0x8b, + 0x09, 0xe0, 0xd6, 0x89, 0x14, 0x6a, 0x19, 0x09, + 0x0a, 0x33, 0x8b, 0xab, 0x82, 0xcb, 0x20, 0x8f, + 0x74, 0x2a, 0x6c, 0xb3, 0xc6, 0xe8, 0x18, 0x89, + 0x09, 0xb6, 0xaf, 0x20, 0xcd, 0xea, 0x74, 0x14, + 0x48, 0x61, 0xe8, 0x4d, 0x50, 0x12, 0x9f, 0x5e, + 0xb8, 0x10, 0x53, 0x3b, 0x74, 0xd9, 0xd0, 0x95, + 0x13, 0xdc, 0x14, 0xcf, 0x0c, 0xa1, 0x90, 0xfd, + 0xa2, 0x58, 0x12, 0xb2, 0x00, 0x2c, 0x5b, 0x7a, + 0x2a, 0x76, 0x80, 0x20, 0x82, 0x39, 0xa2, 0x21, + 0xf8, 0x7a, 0xec, 0xae, 0x82, 0x6a, 0x5c, 0xd3, + 0x04, 0xd9, 0xbd, 0xe4, 0x53, 0xc9, 0xdf, 0x67, + 0xaa, 0x5c, 0xaf, 0xa6, + }; + + uint8_t key[16]; + uint8_t iv[iv_SZ]; + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + + memset(key, 0x44, sizeof(key)); + memset(iv, 0xEE, iv_SZ); + memset(plaintext, 0xAA, SZ); + + psa_key_id_t key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_OFB); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key, sizeof(key), &key_id)); + psa_reset_key_attributes(&attributes); + + for (size_t chunk = 1; chunk < SZ; chunk++) { + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len = 0, total_out = 0; + + memset(iv, 0xEE, iv_SZ); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, PSA_ALG_OFB)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += chunk) { + size_t this_part = SZ - offset < chunk ? SZ - offset : chunk; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out, + SZ - total_out, &out_len)); + total_out += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher, ciphertext, SZ); + + psa_cipher_abort(&enc_op); + + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + total_out = 0; + memset(iv, 0xEE, iv_SZ); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, PSA_ALG_OFB)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + for (size_t offset = 0; offset < SZ; offset += chunk) { + size_t this_part = SZ - offset < chunk ? SZ - offset : chunk; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out += out_len; + } + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out, + SZ - total_out, &out_len)); + total_out += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + psa_cipher_abort(&dec_op); + } + + free(plaintext); + free(ciphertext); + free(decryptedtext); + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-CFB-128", "[psa-aes]") +{ + const size_t SZ = 1000; + const size_t iv_SZ = 16; + const uint8_t expected_cipher_end[] = { + 0xf3, 0x64, 0x20, 0xa1, 0x70, 0x2a, 0xd9, 0x3f, + 0xb7, 0x48, 0x8c, 0x2c, 0x1f, 0x65, 0x53, 0xc2, + 0xac, 0xfd, 0x82, 0xe5, 0x31, 0x24, 0x1f, 0x30, + 0xaf, 0xcc, 0x8d, 0xb3, 0xf3, 0x63, 0xe1, 0xa0, + }; + + const uint8_t iv_seed[] = { + 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, + }; + uint8_t iv[iv_SZ]; + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + + memcpy(iv, iv_seed, iv_SZ); + memset(plaintext, 0x3A, SZ); + memset(decryptedtext, 0x0, SZ); + + psa_key_id_t key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CFB); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + psa_reset_key_attributes(&attributes); + + psa_cipher_operation_t enc_op = PSA_CIPHER_OPERATION_INIT; + size_t out_len = 0, total_out = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_encrypt_setup(&enc_op, key_id, PSA_ALG_CFB)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&enc_op, iv, iv_SZ)); + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&enc_op, plaintext, SZ, ciphertext, SZ, &out_len)); + total_out += out_len; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&enc_op, ciphertext + total_out, SZ - total_out, &out_len)); + total_out += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_end, ciphertext + SZ - sizeof(expected_cipher_end), sizeof(expected_cipher_end)); + + psa_cipher_operation_t dec_op = PSA_CIPHER_OPERATION_INIT; + total_out = 0; + memcpy(iv, iv_seed, iv_SZ); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_decrypt_setup(&dec_op, key_id, PSA_ALG_CFB)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_set_iv(&dec_op, iv, iv_SZ)); + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_update(&dec_op, ciphertext, SZ, decryptedtext, SZ, &out_len)); + total_out += out_len; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_cipher_finish(&dec_op, decryptedtext + total_out, SZ - total_out, &out_len)); + total_out += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out); + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + psa_cipher_abort(&enc_op); + psa_cipher_abort(&dec_op); + psa_destroy_key(key_id); + + free(plaintext); + free(ciphertext); + free(decryptedtext); +} + + +TEST_CASE("PSA AES-CBC one-shot", "[psa-aes]") +{ + const size_t SZ = 1600; + const size_t iv_SZ = 16; + + // allocate internal memory + uint8_t *plaintext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + uint8_t *ciphertext = heap_caps_malloc(SZ + iv_SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + uint8_t *decryptedtext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + + TEST_ASSERT_NOT_NULL(plaintext); + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(decryptedtext); + + memset(plaintext, 0x3A, SZ); + memset(decryptedtext, 0x0, SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(psa_import_key(&attributes, key_256, sizeof(key_256), &key_id), PSA_SUCCESS); + + psa_reset_key_attributes(&attributes); + + size_t ciphertext_len = 0; + /* Encrypt the plaintext */ + TEST_ASSERT_EQUAL(psa_cipher_encrypt(key_id, alg, plaintext, SZ, ciphertext, SZ + iv_SZ, &ciphertext_len), PSA_SUCCESS); + + TEST_ASSERT_EQUAL_size_t(ciphertext_len, SZ + iv_SZ); + + size_t decryptedtext_len = 0; + /* Decrypt the ciphertext */ + TEST_ASSERT_EQUAL(psa_cipher_decrypt(key_id, alg, ciphertext, SZ + iv_SZ, decryptedtext, SZ, &decryptedtext_len), PSA_SUCCESS); + + TEST_ASSERT_EQUAL_size_t(decryptedtext_len, SZ); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + free(plaintext); + free(ciphertext); + free(decryptedtext); + + /* Destroy the key */ + psa_destroy_key(key_id); +} diff --git a/components/mbedtls/test_apps/main/test_psa_aes_gcm.c b/components/mbedtls/test_apps/main/test_psa_aes_gcm.c new file mode 100644 index 00000000000..666714d66a0 --- /dev/null +++ b/components/mbedtls/test_apps/main/test_psa_aes_gcm.c @@ -0,0 +1,203 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include + +#include "esp_log.h" + +#include "psa/crypto.h" + +#include "unity.h" + +static const uint8_t key_256[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +}; + +TEST_CASE("PSA AES-GCM multipart", "[psa-aes-gcm]") +{ + const size_t SZ = 100; + const size_t iv_SZ = 12; // GCM typically uses 12 bytes IV + const size_t tag_SZ = 16; // GCM tag size + const size_t aad_SZ = 16; // Size of Additional Authenticated Data + const size_t part_size = 8; + + size_t tag_length = 0; + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ); + uint8_t *decryptedtext = malloc(SZ); + uint8_t iv[iv_SZ]; + uint8_t tag[tag_SZ]; + uint8_t aad[aad_SZ]; + + TEST_ASSERT_NOT_NULL(plaintext); + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(decryptedtext); + + // Initialize test data + memset(plaintext, 0x3A, SZ); + memset(decryptedtext, 0x0, SZ); + memset(iv, 0x3B, iv_SZ); + memset(aad, 0x3C, aad_SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_GCM; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + + psa_reset_key_attributes(&attributes); + + /* Encrypt */ + psa_aead_operation_t enc_op = PSA_AEAD_OPERATION_INIT; + size_t out_len, total_out_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_encrypt_setup(&enc_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_lengths(&enc_op, aad_SZ, SZ)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_nonce(&enc_op, iv, iv_SZ)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update_ad(&enc_op, aad, aad_SZ)); + + // Process the plaintext in parts + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + // Finish encryption and get the tag + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_finish(&enc_op, + ciphertext + total_out_len, + SZ - total_out_len, + &out_len, + tag, + tag_SZ, + &tag_length)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + /* Decrypt */ + psa_aead_operation_t dec_op = PSA_AEAD_OPERATION_INIT; + total_out_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_decrypt_setup(&dec_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_lengths(&dec_op, aad_SZ, SZ)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_nonce(&dec_op, iv, iv_SZ)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update_ad(&dec_op, aad, aad_SZ)); + + // Process the ciphertext in parts + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + // Verify the tag and finish decryption + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_verify(&dec_op, + decryptedtext + total_out_len, + SZ - total_out_len, + &out_len, + tag, + tag_SZ)); + total_out_len += out_len; + TEST_ASSERT_EQUAL_size_t(SZ, total_out_len); + + // Verify the decrypted data matches the original plaintext + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + /* Cleanup */ + free(plaintext); + free(ciphertext); + free(decryptedtext); + + psa_aead_abort(&enc_op); + psa_aead_abort(&dec_op); + + /* Destroy the key */ + psa_destroy_key(key_id); +} + +TEST_CASE("PSA AES-GCM one-shot", "[psa-aes-gcm]") +{ + const size_t SZ = 100; + const size_t iv_SZ = 12; // GCM typically uses 12 bytes IV + const size_t tag_SZ = 16; // GCM tag size + const size_t aad_SZ = 16; // Size of Additional Authenticated Data + + // Allocate memory with proper alignment + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ + tag_SZ); + uint8_t *decryptedtext = malloc(SZ); + uint8_t *iv = malloc(iv_SZ); + uint8_t *aad = malloc(aad_SZ); + + TEST_ASSERT_NOT_NULL(plaintext); + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(decryptedtext); + TEST_ASSERT_NOT_NULL(iv); + TEST_ASSERT_NOT_NULL(aad); + + // Initialize test data + memset(plaintext, 0x3A, SZ); + memset(ciphertext, 0, SZ + tag_SZ); + memset(decryptedtext, 0x0, SZ); + memset(iv, 0x3B, iv_SZ); + memset(aad, 0x3C, aad_SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_GCM; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + psa_reset_key_attributes(&attributes); + + size_t output_length; + + /* One-shot encrypt */ + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_encrypt(key_id, alg, + iv, iv_SZ, + aad, aad_SZ, + plaintext, SZ, + ciphertext, SZ + tag_SZ, + &output_length)); + + TEST_ASSERT_EQUAL_size_t(SZ + tag_SZ, output_length); + + /* One-shot decrypt */ + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_decrypt(key_id, alg, + iv, iv_SZ, + aad, aad_SZ, + ciphertext, SZ + tag_SZ, + decryptedtext, SZ, + &output_length)); + + TEST_ASSERT_EQUAL_size_t(SZ, output_length); + + // Verify the decrypted data matches the original plaintext + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + /* Cleanup */ + free(plaintext); + free(ciphertext); + free(decryptedtext); + free(iv); + free(aad); + + /* Destroy the key */ + psa_destroy_key(key_id); +} diff --git a/components/mbedtls/test_apps/main/test_psa_cmac.c b/components/mbedtls/test_apps/main/test_psa_cmac.c new file mode 100644 index 00000000000..a22878f2638 --- /dev/null +++ b/components/mbedtls/test_apps/main/test_psa_cmac.c @@ -0,0 +1,398 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* PSA CMAC test +*/ +#include +#include +#include +#include +#include "psa/crypto.h" +#include "unity.h" +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "esp_heap_caps.h" +#include "test_utils.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "esp_memory_utils.h" + +#if CONFIG_MBEDTLS_CMAC_C +static const uint8_t key_128[] = { + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, +}; + +static const uint8_t key_256[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +}; + +static const uint8_t test_data[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 +}; + +// Expected CMAC values from the mbedtls implementation +static const uint8_t expected_cmac_128[] = { + 0x93, 0xae, 0x18, 0x36, 0xdf, 0xbd, 0x91, 0x06, + 0xa5, 0xd1, 0x84, 0x5c, 0xe5, 0x61, 0x02, 0xe2, +}; + +static const uint8_t expected_cmac_256[] = { + 0x35, 0x17, 0x99, 0xb0, 0xfd, 0xb1, 0x5b, 0x47, + 0x98, 0xe3, 0x47, 0xef, 0xa3, 0xb4, 0xe1, 0x89, +}; + +static const uint8_t expected_cmac_zero_length[] = { + 0xd8, 0xa8, 0x58, 0x43, 0x62, 0xe9, 0x93, 0xf8, + 0xd5, 0x29, 0x24, 0xf6, 0x39, 0x07, 0xc4, 0x88, +}; + +TEST_CASE("PSA CMAC AES-128 test", "[psa_cmac]") +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + + // Set up key attributes + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + + // Import the key + status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Allocate internal memory for CMAC output + uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC), + MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(cmac); + + size_t cmac_length = 0; + + // Calculate CMAC + status = psa_mac_compute(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC), + &cmac_length); + ESP_LOGI("PSA CMAC AES-128", "Status: %ld", status); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(16, cmac_length); + ESP_LOG_BUFFER_HEXDUMP("CMAC AES-128", cmac, cmac_length, ESP_LOG_INFO); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac, 16); + + // Verify CMAC + status = psa_mac_verify(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + expected_cmac_128, sizeof(expected_cmac_128)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Cleanup + psa_destroy_key(key_id); + free(cmac); + // mbedtls_psa_crypto_free(); +} + +TEST_CASE("PSA CMAC AES-256 test", "[psa_cmac]") +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + + // Set up key attributes + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 256); + + // Import the key + status = psa_import_key(&attributes, key_256, sizeof(key_256), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Allocate internal memory for CMAC output + uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 256, PSA_ALG_CMAC), + MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(cmac); + + size_t cmac_length = 0; + + // Calculate CMAC + status = psa_mac_compute(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 256, PSA_ALG_CMAC), + &cmac_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(16, cmac_length); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_256, cmac, 16); + + // Verify CMAC + status = psa_mac_verify(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + expected_cmac_256, sizeof(expected_cmac_256)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Cleanup + psa_destroy_key(key_id); + free(cmac); + // mbedtls_psa_crypto_free(); +} + +TEST_CASE("PSA CMAC AES-128 multipart test", "[psa_cmac]") +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + + // Set up key attributes + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + + // Import the key + status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Allocate internal memory for CMAC output + uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC), + MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(cmac); + + size_t cmac_length = 0; + + // Test multipart operation with different chunk sizes + for (size_t chunk_size = 1; chunk_size < sizeof(test_data); chunk_size++) { + // Setup operation + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + // Process data in chunks + for (size_t offset = 0; offset < sizeof(test_data); offset += chunk_size) { + size_t current_chunk_size = (offset + chunk_size > sizeof(test_data)) ? + (sizeof(test_data) - offset) : chunk_size; + + status = psa_mac_update(&operation, test_data + offset, current_chunk_size); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + } + + // Finish operation + status = psa_mac_sign_finish(&operation, cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC), + &cmac_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(16, cmac_length); + // Verify result + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac, 16); + } + + // Cleanup + psa_destroy_key(key_id); + free(cmac); + // mbedtls_psa_crypto_free(); +} + +TEST_CASE("PSA CMAC AES-128 multipart verify test", "[psa_cmac]") +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + + // Set up key attributes + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + + // Import the key + status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Allocate internal memory for CMAC output + uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC), + MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(cmac); + + size_t cmac_length = 0; + + status = psa_mac_compute(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC), + &cmac_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(16, cmac_length); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac, 16); + + // Verify CMAC multipart + psa_mac_operation_t verify_operation = PSA_MAC_OPERATION_INIT; + status = psa_mac_verify_setup(&verify_operation, key_id, PSA_ALG_CMAC); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + status = psa_mac_update(&verify_operation, test_data, sizeof(test_data)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + status = psa_mac_verify_finish(&verify_operation, cmac, cmac_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Modify one byte of cmac and check for failure + cmac[0] = cmac[0] + 1; + + status = psa_mac_verify_setup(&verify_operation, key_id, PSA_ALG_CMAC); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + status = psa_mac_update(&verify_operation, test_data, sizeof(test_data)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + status = psa_mac_verify_finish(&verify_operation, cmac, cmac_length); + TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status); + + // Cleanup + psa_destroy_key(key_id); + free(cmac); + // mbedtls_psa_crypto_free(); +} + +TEST_CASE("PSA CMAC zero-length test", "[psa_cmac]") +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + + // Set up key attributes + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + + // Import the key + status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Allocate internal memory for CMAC output + uint8_t *cmac = heap_caps_malloc(PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC), + MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); + TEST_ASSERT_NOT_NULL(cmac); + + size_t cmac_length = 0; + + // Calculate CMAC on zero-length data + status = psa_mac_compute(key_id, PSA_ALG_CMAC, + NULL, 0, + cmac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC), + &cmac_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(16, cmac_length); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_zero_length, cmac, 16); + + // Verify CMAC + status = psa_mac_verify(key_id, PSA_ALG_CMAC, + NULL, 0, + expected_cmac_zero_length, sizeof(expected_cmac_zero_length)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Cleanup + psa_destroy_key(key_id); + free(cmac); + // mbedtls_psa_crypto_free(); +} + +TEST_CASE("PSA CMAC memory alignment test", "[psa_cmac]") +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + + // Set up key attributes + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + + // Import the key + status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Allocate memory with different capabilities + uint8_t *cmac_internal = heap_caps_malloc(16, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); + uint8_t *cmac_dma = heap_caps_malloc(16, MALLOC_CAP_DMA|MALLOC_CAP_8BIT); + + TEST_ASSERT_NOT_NULL(cmac_internal); + TEST_ASSERT_NOT_NULL(cmac_dma); + + size_t cmac_length_internal = 0; + size_t cmac_length_dma = 0; + + // Calculate CMAC with internal memory + status = psa_mac_compute(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + cmac_internal, 16, + &cmac_length_internal); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(16, cmac_length_internal); + + // Calculate CMAC with DMA-capable memory + status = psa_mac_compute(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + cmac_dma, 16, + &cmac_length_dma); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + TEST_ASSERT_EQUAL(16, cmac_length_dma); + + // Results should be identical + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac_internal, 16); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cmac_128, cmac_dma, 16); + TEST_ASSERT_EQUAL_HEX8_ARRAY(cmac_internal, cmac_dma, 16); + + // Cleanup + psa_destroy_key(key_id); + free(cmac_internal); + free(cmac_dma); + // mbedtls_psa_crypto_free(); +} + +TEST_CASE("PSA CMAC verify failure test", "[psa_cmac]") +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + + // Set up key attributes + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + + // Import the key + status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Create an invalid CMAC by modifying one byte + uint8_t invalid_cmac[16]; + memcpy(invalid_cmac, expected_cmac_128, 16); + invalid_cmac[0] ^= 0x01; // Flip one bit + + // Verify should fail with the modified CMAC + status = psa_mac_verify(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + invalid_cmac, sizeof(invalid_cmac)); + TEST_ASSERT_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status); + + // Verify should succeed with the correct CMAC + status = psa_mac_verify(key_id, PSA_ALG_CMAC, + test_data, sizeof(test_data), + expected_cmac_128, sizeof(expected_cmac_128)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Cleanup + psa_destroy_key(key_id); + // mbedtls_psa_crypto_free(); +} +#endif /* CONFIG_MBEDTLS_CMAC_C */ diff --git a/components/mbedtls/test_apps/main/test_psa_gcm.c b/components/mbedtls/test_apps/main/test_psa_gcm.c new file mode 100644 index 00000000000..45e3493a41d --- /dev/null +++ b/components/mbedtls/test_apps/main/test_psa_gcm.c @@ -0,0 +1,210 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include + +#include "esp_log.h" + +#include "psa/crypto.h" +#include "unity.h" + +static const uint8_t key_256[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +}; + +TEST_CASE("PSA ARIA-GCM multipart", "[psa-gcm]") +{ + // TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_crypto_init()); + + const size_t SZ = 100; + const size_t iv_SZ = 12; // GCM typically uses 12 bytes IV + const size_t tag_SZ = 16; // GCM tag size + const size_t aad_SZ = 16; // Size of Additional Authenticated Data + const size_t part_size = 8; + + // Allocate memory with proper alignment + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ + tag_SZ); + uint8_t *decryptedtext = malloc(SZ); + uint8_t *iv = malloc(iv_SZ); + uint8_t *aad = malloc(aad_SZ); + + TEST_ASSERT_NOT_NULL(plaintext); + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(decryptedtext); + TEST_ASSERT_NOT_NULL(iv); + TEST_ASSERT_NOT_NULL(aad); + + // Initialize test data + memset(plaintext, 0x3A, SZ); + memset(ciphertext, 0, SZ + tag_SZ); + memset(decryptedtext, 0x0, SZ); + memset(iv, 0x3B, iv_SZ); + memset(aad, 0x3C, aad_SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_GCM; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ARIA); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + psa_reset_key_attributes(&attributes); + + /* Encrypt */ + psa_aead_operation_t enc_op = PSA_AEAD_OPERATION_INIT; + size_t out_len, total_out_len = 0; + size_t tag_length = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_encrypt_setup(&enc_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_lengths(&enc_op, aad_SZ, SZ)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_nonce(&enc_op, iv, iv_SZ)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update_ad(&enc_op, aad, aad_SZ)); + + // Process the plaintext in parts + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update(&enc_op, plaintext + offset, this_part, + ciphertext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + // Finish encryption and get the tag + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_finish(&enc_op, + ciphertext + total_out_len, + SZ + tag_SZ - total_out_len, + &out_len, + ciphertext + SZ, + tag_SZ, + &tag_length)); + total_out_len += out_len; + + /* Decrypt */ + psa_aead_operation_t dec_op = PSA_AEAD_OPERATION_INIT; + total_out_len = 0; + + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_decrypt_setup(&dec_op, key_id, alg)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_lengths(&dec_op, aad_SZ, SZ)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_set_nonce(&dec_op, iv, iv_SZ)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update_ad(&dec_op, aad, aad_SZ)); + + // Process the ciphertext in parts + for (size_t offset = 0; offset < SZ; offset += part_size) { + size_t this_part = SZ - offset < part_size ? SZ - offset : part_size; + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_update(&dec_op, ciphertext + offset, this_part, + decryptedtext + offset, this_part, &out_len)); + total_out_len += out_len; + } + + // Verify the tag and finish decryption + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_verify(&dec_op, + decryptedtext + total_out_len, + SZ - total_out_len, + &out_len, + ciphertext + SZ, + tag_SZ)); + total_out_len += out_len; + + // Verify the decrypted data matches the original plaintext + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + /* Cleanup */ + free(plaintext); + free(ciphertext); + free(decryptedtext); + free(iv); + free(aad); + + psa_aead_abort(&enc_op); + psa_aead_abort(&dec_op); + + /* Destroy the key */ + psa_destroy_key(key_id); + // mbedtls_psa_crypto_free(); +} + +TEST_CASE("PSA ARIA-GCM one-shot", "[psa-gcm]") +{ + // TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_crypto_init()); + + const size_t SZ = 100; + const size_t iv_SZ = 12; // GCM typically uses 12 bytes IV + const size_t tag_SZ = 16; // GCM tag size + const size_t aad_SZ = 16; // Size of Additional Authenticated Data + + // Allocate memory with proper alignment + uint8_t *plaintext = malloc(SZ); + uint8_t *ciphertext = malloc(SZ + tag_SZ); + uint8_t *decryptedtext = malloc(SZ); + uint8_t *iv = malloc(iv_SZ); + uint8_t *aad = malloc(aad_SZ); + + TEST_ASSERT_NOT_NULL(plaintext); + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(decryptedtext); + TEST_ASSERT_NOT_NULL(iv); + TEST_ASSERT_NOT_NULL(aad); + + // Initialize test data + memset(plaintext, 0x3A, SZ); + memset(ciphertext, 0, SZ + tag_SZ); + memset(decryptedtext, 0x0, SZ); + memset(iv, 0x3B, iv_SZ); + memset(aad, 0x3C, aad_SZ); + + /* Import a key */ + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_GCM; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ARIA); + psa_set_key_bits(&attributes, sizeof(key_256) * 8); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_import_key(&attributes, key_256, sizeof(key_256), &key_id)); + psa_reset_key_attributes(&attributes); + + size_t output_length; + + /* One-shot encrypt */ + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_encrypt(key_id, alg, + iv, iv_SZ, + aad, aad_SZ, + plaintext, SZ, + ciphertext, SZ + tag_SZ, + &output_length)); + + TEST_ASSERT_EQUAL_size_t(SZ + tag_SZ, output_length); + + /* One-shot decrypt */ + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_aead_decrypt(key_id, alg, + iv, iv_SZ, + aad, aad_SZ, + ciphertext, SZ + tag_SZ, + decryptedtext, SZ, + &output_length)); + + TEST_ASSERT_EQUAL_size_t(SZ, output_length); + + // Verify the decrypted data matches the original plaintext + TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); + + /* Cleanup */ + free(plaintext); + free(ciphertext); + free(decryptedtext); + free(iv); + free(aad); + + /* Destroy the key */ + psa_destroy_key(key_id); + // mbedtls_psa_crypto_free(); +} diff --git a/components/mbedtls/test_apps/main/test_psa_hmac.c b/components/mbedtls/test_apps/main/test_psa_hmac.c new file mode 100644 index 00000000000..11f8695f3f9 --- /dev/null +++ b/components/mbedtls/test_apps/main/test_psa_hmac.c @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* PSA HMAC test +*/ + +#include "psa/crypto.h" +#include "unity.h" +static const uint8_t key_128[] = { + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, +}; + +static const uint8_t test_data[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 +}; + +static const uint8_t expected_hmac_128[] = { + 0x00, 0x7a, 0x5a, 0xd6, 0x54, 0x96, 0x5b, 0xcd, + 0x30, 0xc1, 0x60, 0x62, 0xec, 0xac, 0x75, 0xfb, + 0x87, 0x71, 0x0e, 0x13 +}; + +TEST_CASE("PSA HMAC SHA-1 test", "[psa_hmac]") +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + + // Initialize PSA Crypto + status = PSA_SUCCESS; + // TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + // Set up key attributes + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(PSA_ALG_SHA_1)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); + psa_set_key_bits(&attributes, 128); + + uint8_t *hmac = malloc(PSA_HASH_LENGTH(PSA_ALG_SHA_1)); + TEST_ASSERT_NOT_NULL(hmac); + + status = psa_import_key(&attributes, key_128, sizeof(key_128), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + size_t mac_length = 0; + status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_1), + test_data, sizeof(test_data), + hmac, PSA_HASH_LENGTH(PSA_ALG_SHA_1), &mac_length); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + status = psa_mac_verify(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_1), + test_data, sizeof(test_data), + expected_hmac_128, sizeof(expected_hmac_128)); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + psa_destroy_key(key_id); + psa_reset_key_attributes(&attributes); + free(hmac); +} diff --git a/components/mbedtls/test_apps/main/test_psa_rsa.c b/components/mbedtls/test_apps/main/test_psa_rsa.c new file mode 100644 index 00000000000..6cc9e1c5f9b --- /dev/null +++ b/components/mbedtls/test_apps/main/test_psa_rsa.c @@ -0,0 +1,303 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include + +#include "esp_log.h" + +#include "psa/crypto.h" +#include "mbedtls/pk.h" +#include "mbedtls/pem.h" +#include "mbedtls/error.h" +#include "unity.h" +#include "ccomp_timer.h" +#include "test_utils.h" + +typedef enum { + PSA_RSA_KEY_SIZE_2048, + PSA_RSA_KEY_SIZE_3072, + PSA_RSA_KEY_SIZE_4096, +} psa_rsa_key_size_t; + +static const char privkey_4096_buf[] = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIJKAIBAAKCAgEA1blr9wfIzTylroJHxcoq+YFA765gF5vj9b6tfaPG0XQExSkjndHv5sra4ar7T+k2sBB4OcKKeGHkNk6wk8tGmOS79r2L74XZs1eB0UruG+huV7Sd+YiWzwN8y9jGImA9hIkf1qxIvkco5WTmT7cVwUnCQ7qiiVadD/LgyeGD04yKZpzv9UJzfjXz5ITTn/ejcn7423M9qz41nhRWwK4zw1jv7IB57d1dWOCbN3RO4dvfVndCz8DOmLzJrZAkLsz39vppbIwbMqTXKFxWqzZY2xrYmnMx9p3v4hLeju7ls3fsekESonoP0C76u50wJfZWO2XcIUo4pue/jHi2o9KouhLXW/vyasplXvE6FFrBjSpsm1Nar4KQMUolEkUbO9baGcQvH9G5WOH0kwPt7AOSqM2EUPvBd7Jv0tbMI/BRZVVltC/t6WhannCM/I6nZrlNe5tie/qYlFu474jp5/tpa8RykkDxwl9whejIqd4iQbvDiP/GXgBYtDJ9VU/S2KqHJhQFLDi+F3+ewOcF391fgt1e1J2vNYLKZOfxTOl/1vJbU/2IjRWTRQ7cXnmpR/GNCRfgH2as6Z/0oknBSVephguDnO5QlveP4Cx2EOVY/A/KgDpu8PumSrlIk+YQgLxdKsXaVI6eDY4rY7q2uCJH3yIAfZJXEeD+ResUuSZltvECAwEAAQKCAgBwR89+oipOGHR6b5tBP+q/1bXFtXhqLs3eBuSiQu5qj2cKJYi+mtJMD3paYDdTThQa/ywKPDf+8n6wQTrnCj32iQRupjnkBg/O9kQPLixVoRCHJy5vL+D6tLxVY3cEDEeFX3zIjQ5SWJQVn6KXcnoNZ7CVYHGPcV9mR5TsuntFImp7aituUBDY14NgJKABRFosBqS6tZpKYo5MlCbXZy1ujUTOnNhxrIAj9yvUQFhIs/hrNpB1ELf46gWSF03LAIesyvWjvx9yxcL7QzeNDyozQbFVwvsWsvaZcIxXzw4B8RjdSV5+2V2BY4z6D6SB7R50ahjxrEqC9PFe3PQmsL9OvFjV9idYwFOhxiWXGjIm3wwFFLOj3e0TShscj2Iw+Ghd3wApvSdBZxzdjap1NHC+Q6yYU+BnivxUHcopVPPM3rsLndyRC6zfrQw/OkOlAP3bNL1hRedPRmRDOz0V1ihEpgC1VfXx6XOu4eg8xWiJgWX+BGvT5GWjfQg2hB1Jm344r3l0eLhr25dO80GIac2QGT2+WmYkXcsQ3AiqAn2VF8UB5mU+Iyh96jmSFVVltGZgfp98yFYN63/7wB++lhVQmJZwbglutng1qjQBFslIULddIHiYvF+AVvkrO3Hc2zg8rT91tbE13k06A1zlNGcQuQKLax8e+2/BNjsZU2E4uQKCAQEA7L4obKWYRHgG6j1VEDRrQU8Vkm4L11B+ZD/rsEh3q7LbzViOPv+1dZ40jX2qYScWyaefI46bukJlk/mlNv4Dh3EnSFvHPCInDM3oImCYImwUx0hkbSRyRNwlwRwx81LJzIR84cCqpNWrXXcplomUSM62ea1E1vtNSZs9Bg2OLoWvFOTPgk/xDi6ezdb6JFiId6cARup/bmZ363mg8jCq0wpTLVdUGrezfMj4GpB1uQET5xqXleumQu/04cHPOfXwpV0ikIOId/ldY/PetiRd86B32aB2Xd4fHUpxHMY+63MFmL6SsqMQJMPubv+eIrOId4HhT+nXNFBZXolT5XG5NwKCAQEA5xvvccHNyCTL0AebxD6EihWnp0/Dd0DwXWxZw0Yhhc9xa/W/QtygB6kPb35oKGvCKdm4dWCIGln03dU5D6CMNkJlbkxpo8gybz34SJ/6OvU836rBLHZXE3Xiqbe5XkdMdarA7kTEhEUqekDXPxhws9dWh0YjtAnBPpm1GQppiykI2edkiIhRgju5ghe+/UjAjxrEgCKZeAODh46hwZHERRKQN2MFUOFcOVDq+2wTJem9r3h1uBQAiZn8PDyx0rlRkwH2dZSSauVW+I713N0JGucOV7FeMO0ebioqqckh0i91ZJNH//Io8Sp8WuBsU/vcP9jT+5BDkCbc71BRO/AFFwKCAQBj4a6oeA0QBhvUw9+ZoKQHv9f4GZnBU+KfZSCJFWn39NQrhMsu5S+n2gGOGJDDwHwqxB+uHsKxCMZWciM0WmMex6ytKJucUURscIsZxespyrPRiEdmjNPxHXiISt8AK9OcB+GwVVsphERygI35Rz5aoWv3VhUPJqNrBKXwYdO06Q3/ILIz5oprU1wIuER9BSU+ZiUFxnXRHEZIAN7Yj5Piyh5hqNCBHTQK17dlbcFdNokxHdUKmYth/l8wyFYnvA21lt+4XOY8x+aQ/xjde+ZvnSozlTGbVNWHxBqI61MsfzDDStQVrhpniIqWJh6PwXM4CIII9z2mgqfR7NqKmTptAoIBAQDTYQOigmZbFvyrayoXVi8XtTLAnv3jByxR5pY7OtvSbagJ3J1w5CYim4iYq39M6TKP4KkMApy5rWl/tFQabPeRcS0gsxc0TBmFEaMTme7fGgrxcFZ6+koubHZCUN5k0sWmIeWQiKlNaY2uf7vf49TBSMXFuGtTclCjlybCnnlmZMPJuhCDqFsUyNelm15+f5pPyWXM5NiFooEc7WIZj996Zb4uSo1EKruVWONzzqe814s9AOp60SCkuoiv97uVRxbLZNItPRSmXNktQmSx/CEl0AuYPYwvJ9HbZQncfTBH9ExlDyidernjyr4uyHGMZyJN614ICy0gncsZv9ZtAd1FAoIBAA4toGPU/VcKFmK92zgO05jsg5vJzw5xeoxRWKrLg7iby6Su6BuNgaVwfYWeZuOhnXakid7FvFXKH6x44o9gyFm5bKqFhaXDzAnxzqcLeM5V+gititOsstpZCbVOoKQOhgTHyxpFNVX3E/nB8EunydWyhQMxKme//NsRroFm1vWljQKyL3zER82AzyseEpEYZoB/6g0n5uF2lR7KllxeBlINsceQ8g3JkmJTdS1hoXcyUSsZ+EgrRbCykNB5aVC5G3/W1OSZsFHbbMrYHCMnaYKwMqLmOkb11o6nOrJJ4pgHj8CVcp2TNjfy3y0Ru6RZ42b0Q+3LktJBGu9r5d04FgI=\n" + "-----END RSA PRIVATE KEY-----"; + +static const char privkey_2048_buf[] = "-----BEGIN RSA PRIVATE KEY-----\r\n" + "MIIEowIBAAKCAQEA8N8hdkemvj6Tpk975/OWhv9BrTsCBCu+ZYfDb5VI7U2meKBg\r\n" + "3dAkyyhRlY3fNwSRzBUMCzsHjpgnsB40wxOgiwlB9n6PMhq0qUVKAdCpKwFztsKd\r\n" + "JJAsCUC+Zlwxn4RpH6ZnMl3a/njRYjuDyI32kucMP/lBRo7ks1798Gy/j+x1h5xA\r\n" + "vZSlFoEXKjCC6S1DWhALePuZnk4m/jGP6g+YfyJXSTqsenKa/DcWndfn/JoElZ0J\r\n" + "nhud8lBXwVe6mMheE1yqfL+VTU1nwg/TPNZrZsFz2sXig/RQCKt6LuSuzhRpsLp+\r\n" + "BdwqEs9xrwlhZnp7j4kQBomISd6kAxQfYVROHQIDAQABAoIBAHgtO4rB8QWWPyCJ\r\n" + "I670r7OnA2OkvzrJgHMzq2SuvPX4+gfRLMM+qDzcXugZIrdWhk+maJ3p07lnXNXY\r\n" + "HEcAMedstQaA2n0LKfwSX/xL2TtlvBABRVoKvI3ZSaXUdcW60KBD69ULUsoICZ/T\r\n" + "Rcr4WX+t20TH3bOQc7ayvEwKVgE95xIUpTH9asw8uOPvKxW2j5OLQgZuWrWyUDg0\r\n" + "MFh92PhWtw3i5zq6OpTTsFJeceKYV/VstIYjZ+FslmhjQxJbr+2DJRbpHXKceqy6\r\n" + "9yWlSV0EM7neFCHlDa2WPhK8we+6IvMiNVQKj46fHGYNBaW/ZSX7TiG5J0Uqj2e9\r\n" + "0MUGJ8ECgYEA+frJabhfzW5+JfGjTObeznJZE6fAOjFzaBIwFu8Kz2mIjYpQlwVK\r\n" + "EepMkv2KkrJuqS4GnI+Nkq7G0BAUyUj9tTJ3HQzvtJrxsnxVi99Yofx1s1P4YAnu\r\n" + "c8t3ElJoQ4BRoQIs/hIvyYn22IxllBHiGESrnPQ38D82xyXQgd6S8JkCgYEA9qww\r\n" + "j7jx6Xpy/D1Dq8Dvalm7pz3J+yHnti4w2cqZ67grUoyGnNPtciNDdfi4JzLiKkUu\r\n" + "SDS3DacvFpFyND0m8sbpMjnR8Rvhj+bfH8KcOAowD+YR/+6vSb/P/aBt6gYXcaBn\r\n" + "cjepx+sE81mnC7UrHb4TjG4hO5t3ZTc6X28gyCUCgYAMZn9lSisecrO5SCJUp0M4\r\n" + "NH3stq6XdGqIKBbQnG0J2u9WLh1PUIjbGKdRx1f/bPCGXe0gCRL5yse7/IA7d+51\r\n" + "9ZnpDAI8EE+bDgXkWWD5MB/alHjGstdsURSICSR47L2f4g6/T8GlGr3vAg/r53My\r\n" + "xv1IXOkFdu1NtbeBKbxaSQKBgENDmw5mAVmIcXiFAEICn4ahp4EoYT6g9T2BhQKu\r\n" + "s6BKnU2qUj7Lr5ETOp8dzqGpx3B9Yux/q3cGotmFmd3S2x8SzJ5MlAoqbyy9aRSR\r\n" + "DeZeKNL9CuV+YcA7lOz1ZWOOe7AZbHwB38NLPBNb3CheI769iTkfAuLtNvabw8go\r\n" + "VokdAoGBALyvBhW+Squ5tx8NOEgAisakhAVOnT6jcoeKy6FyjcvKaWagmCOCC7Gz\r\n" + "QB9Yf1tJ+3di+aLtWWdmU494iKJHBtPMhfrYltCpxHHQGlUc/GLPY3Z5bBYYYWpb\r\n" + "Wzw4ZvDraKlAs7a9CRwS5cpktk5ptK4rc5noSXkvV+yOT75zXat2\r\n" + "-----END RSA PRIVATE KEY-----\r\n"; + +static const char privkey_3072_buf[] = "-----BEGIN RSA PRIVATE KEY-----\r\n" + "MIIG4wIBAAKCAYEAoMPuYRnHVPP49qiPACIsYBLVuj8xH4XqAuXmurOyPPFfKSch\r\n" + "52dn97sXvfXQw6hj+iPBeMSzbSAompjx4mUHtwn2+EvyXjqUe8qtI0y12uzXgOr8\r\n" + "vdwNLJO1kTmUWxQIa/e6dZpiKcEYYZ6qWNUGVH9IiMB9HdIFLNIdCAAC+gsK+Q0w\r\n" + "OT2CwnGOoZ/PzOXHyfte9pJTDk6nQJDKVTBoOLgVcJoCLwctGf7VJ9YI9+YXJKvW\r\n" + "1ZYq8PXM8KAVE7KHN7KiskJxDLSR4xuplxdT//LIBJMRvxAEPYohe7QvejFjtQc6\r\n" + "WbEJxV/Y4vWHOb2PVGUHATNK2kQ7/N5HgEdxABgLrXQSkGfKKmWwoy/W5TVDS+qX\r\n" + "fR/7WeJa/2e2+ZZVSQtiXdrWSKdgEmVdmM43Aso5ppC2C5QBajHAw2MKMZwxLHbI\r\n" + "nhQJQMJdmRvXI8Kg/+WEgknxQLFWrRW4ss3wR+2KvZ0eynEuzHkQxtUAWB8xgNAH\r\n" + "Bch/tr+xq1g3DFNXAgMBAAECggGAFvaFiScWesLyb8D51AoNjpeCIb0+9gK5vzo5\r\n" + "b7eVIPFVJ1qolBYIGrGFnaOL8zaNOUB8NRTbkB3EzvhDrJPDu1hYB3VJpD330YrM\r\n" + "mjstypyD16049qGE3DYo/BpeX3gID+vtnTi1BsPHCMKSEGg1JEKeCLJ97JGAHbvR\r\n" + "W8AsrKyBH7vLhJGNqNpxhhJ+qwSzOd2G3e9en6+KYkWMMQjeCiP5JAFLiI4c2ha1\r\n" + "OaBv3YDnE1zcLdvqPErPwBsNh6e7QLYbEvQj5mZ84/kCbrwFy//+Bf7to0u6weOy\r\n" + "8E1HU8UKdJfWsKwh+5BGDnKs8qgVQWJdPJWy25PVgkzp0ZnSKzp2AddMCrI2YHRM\r\n" + "Q+G+9bET/D96y7/08EAobDdXCplcPeOVb8ETbQTNTrHJibUCB4fqkN8tR2ZZTQ1F\r\n" + "axhmHDThsVFqWk+629j8c6XOQbx2dvzb7YfLK06ShiBcD0V6E7VFXHzR+x/xA9ir\r\n" + "zUcgLt9zvzj9puxlkhtzBZKcF3nBAoHBANCtY4NDnFoO+QUS59iz9hsoPAe8+S+U\r\n" + "PkvMSN7iziUkiXbXjQsr0v/PLHCuuXRyARBORaI4moLxzbTA1l1C+gBulI29j9zH\r\n" + "GwNnl587u5VCpbzuzr5YwHtp85Y1la2/ti+x0Qaw5uoa8G2TqoU4V6SG0qwinQl2\r\n" + "9mdNZzVmIBMbE0tTTTzc+CRIPBl9lRQR3Ff3o6eUs6uPE6g1lGZR1ydb2MLBM/wV\r\n" + "NgUUf7L5h/s8abrRjS+dnPmtxNgrRZQe9wKBwQDFOQyBzD3xkBgTSFQkU8OgNZyW\r\n" + "gNYglE1vLA+wv49NVAErHfKzYf/yw3fkYLDo9JfTJ3KckU6J815VnPXJFNMvjr2J\r\n" + "ExXG2JSbZHeUBRgExLU0iFlhQaxbAhuJ6PDrkGy+1ZtsJxYCPpifyNwjkZ0QKQlf\r\n" + "n3SwTMXIp0wd80FXVSwKPSuWUlrhByBcJDVwdCIeD8Oi9DrmVe0E9fXDboY2HARb\r\n" + "cgrN3n9jnEF/asIsfaHg8EI2z/EVC+C1mHuZdqECgcA5d4ZwH65vHrB1NT+j7etY\r\n" + "jzv45ZG6CJkfRqLKvqsGj4lLsRCmgusYh3U1kuh/qOWiF+wVQIFMjkqX/IMMK+Wt\r\n" + "OMawQgPcSPind1/J+ikucawy25ET2l0nn4X1V8xgjOsfN1jY/t6YmdKcWo4bIekA\r\n" + "5iAeR2n3sUsqJ6bEjdtHZ61okQg0OqYbV8k1O+BSJpkHoKrw+4J/PGetaxPzGZam\r\n" + "wCRxfcNTKIQ34e1I3G8WQQzc5dh7xGv2VmRfI4uFvwECgcEAuNGAVfZ3KfNVjGRg\r\n" + "bXaNwYncBvIPN5KiigbpYUHyYY3SVnyHHvE8cFwa80plHrlvubGi5vQIfKAzC9m+\r\n" + "PsSkL1H9bgITizcU9BYPNQgc/QL1qJgJ4mkvwk1UT0Wa17WNIrx8HLr4Ffxg/IO3\r\n" + "QCHJ5QX/wbtlF32qbyHP49U8q0GmtqWiPglJHs2V1qMb7Rj3i+JL/F4RAB8PsXFo\r\n" + "8M6XOQfCUYuqckgKaudYPbZm5liJJYkhE8qD6qwp1SNi2GphAoHABjUL8DTHgBWn\r\n" + "sr9/XQyornm0sruHcwr7SmGqIJ/hZUUYd4UfDW76e8SjvhRQ7nkpR3f4+LEBCqaJ\r\n" + "LDJDhg+6AColwKaWRWV9M1GXHhVD4vaTM46JAvH9wbhmJDUORHq8viyHlwO9QKpK\r\n" + "iHE/MtcYb5QBGP5md5wc8LY1lcQazDsJMLlcYNk6ZICNWWrcc2loG4VeOERpHU02\r\n" + "6AsKaaMGqBp/T9wYwFPUzk1i+jWCu66xfCYKvEubNdxT/R5juXrd\r\n" + "-----END RSA PRIVATE KEY-----\r\n"; + +// Keep the old version for reference (has issues with PSA-based PK) +static int pem_to_der_rsa_key(const char *pem_key, size_t pem_key_len, + uint8_t *der_buf, size_t der_buf_size, + uint8_t **der_data_ptr, size_t *der_len) +{ + // Use direct PEM parsing instead of PK layer for PSA compatibility + // return pem_to_der_rsa_key_direct(pem_key, pem_key_len, der_buf, der_buf_size, + // der_data_ptr, der_len); + + mbedtls_pk_context pk; + int ret; + + mbedtls_pk_init(&pk); + + // Parse PEM key + ret = mbedtls_pk_parse_key(&pk, + (const uint8_t *)pem_key, + pem_key_len, + NULL, 0); // No password + if (ret != 0) { + char error_buf[100]; + mbedtls_strerror(ret, error_buf, sizeof(error_buf)); + printf("mbedtls_pk_parse_key failed: -0x%04x - %s\n", -ret, error_buf); + mbedtls_pk_free(&pk); + return ret; + } + + // Write key to DER format + // NOTE: mbedtls_pk_write_key_der writes to the END of the buffer! + // Returns the length on success, or negative error code + printf("Attempting to write DER key (buffer size: %zu)...\n", der_buf_size); + ret = mbedtls_pk_write_key_der(&pk, der_buf, der_buf_size); + if (ret < 0) { + char error_buf[100]; + mbedtls_strerror(ret, error_buf, sizeof(error_buf)); + printf("mbedtls_pk_write_key_der failed: -0x%04x - %s\n", -ret, error_buf); + mbedtls_pk_free(&pk); + return ret; + } + + printf("DER key written successfully, length: %d\n", ret); + + // ret contains the length of DER data + *der_len = ret; + + // Calculate the start position of DER data (at end of buffer) + *der_data_ptr = der_buf + der_buf_size - ret; + + mbedtls_pk_free(&pk); + return 0; +} + +static psa_key_id_t import_rsa_key(psa_rsa_key_size_t key_size) +{ + psa_key_id_t key_id; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + int ret; + + // Convert PEM to DER format + uint8_t *der_buf = calloc(1, 10000); // Buffer for DER-encoded key (data written at end) + uint8_t *der_key = NULL; // Pointer to actual DER data location + size_t der_key_len = 0; + + char *key_buf = NULL; + + if (key_size == PSA_RSA_KEY_SIZE_2048) { + key_buf = (char *)privkey_2048_buf; + } else if (key_size == PSA_RSA_KEY_SIZE_3072) { + key_buf = (char *)privkey_3072_buf; + } else if (key_size == PSA_RSA_KEY_SIZE_4096) { + key_buf = (char *)privkey_4096_buf; + } else { + printf("Unsupported key size for import_rsa_key\n"); + free(der_buf); + return 0; + } + + ret = pem_to_der_rsa_key(key_buf, + strlen(key_buf) + 1, // Include null terminator + der_buf, + 10000, + &der_key, // Returns pointer to DER data + &der_key_len); + TEST_ASSERT_EQUAL(0, ret); + + // Configure key attributes for RSA encryption/decryption + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT); + psa_set_key_usage_flags(&attributes, + PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + size_t key_bits = 0; + if (key_size == PSA_RSA_KEY_SIZE_2048) { + key_bits = 2048; + } else if (key_size == PSA_RSA_KEY_SIZE_3072) { + key_bits = 3072; + } else if (key_size == PSA_RSA_KEY_SIZE_4096) { + key_bits = 4096; + } + psa_set_key_bits(&attributes, key_bits); + + status = psa_import_key(&attributes, + der_key, // Pointer to DER data (at end of buffer) + der_key_len, + &key_id); + if (status != PSA_SUCCESS) { + printf("PSA import failed with error: %ld (0x%x)\n", status, (unsigned int)status); + printf("Expected error codes:\n"); + printf(" PSA_ERROR_INVALID_ARGUMENT = %ld\n", PSA_ERROR_INVALID_ARGUMENT); + printf(" PSA_ERROR_NOT_SUPPORTED = %ld\n", PSA_ERROR_NOT_SUPPORTED); + printf(" PSA_ERROR_INSUFFICIENT_MEMORY = %ld\n", PSA_ERROR_INSUFFICIENT_MEMORY); + } + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + free(der_buf); + psa_reset_key_attributes(&attributes); + return key_id; +} + +TEST_CASE("test performance RSA key operations", "[bignum]") +{ + psa_status_t status; + psa_rsa_key_size_t keysize = PSA_RSA_KEY_SIZE_2048; + for (int i = 0; i < 3; i++) { + // Use der_key (not der_buf) as it points to the actual DER data at end of buffer + psa_key_id_t key_id = import_rsa_key(keysize); + printf("RSA key imported successfully (key_id: %u)\n", (unsigned int)key_id); + + size_t ciphertext_size = 0; + if (keysize == PSA_RSA_KEY_SIZE_2048) { + ciphertext_size = 256; // 2048 bits / 8 + } else if (keysize == PSA_RSA_KEY_SIZE_3072) { + ciphertext_size = 384; // 3072 bits / 8 + } else if (keysize == PSA_RSA_KEY_SIZE_4096) { + ciphertext_size = 512; // 4096 bits / 8 + } else { + printf("Unsupported key size for ciphertext size calculation\n"); + return; + } + + uint8_t plaintext[] = "Test message for RSA encryption"; + size_t plaintext_len = sizeof(plaintext); + uint8_t ciphertext[ciphertext_size]; // RSA 2048-bit key produces 256-byte ciphertext + size_t ciphertext_len = sizeof(ciphertext); + uint8_t decrypted[ciphertext_size]; + size_t decrypted_len = sizeof(decrypted); + size_t encrypt_len = 0; + +#ifdef SOC_CCOMP_TIMER_SUPPORTED + int public_perf, private_perf; + ccomp_timer_start(); +#endif + // Encrypt the plaintext + status = psa_asymmetric_encrypt(key_id, + PSA_ALG_RSA_PKCS1V15_CRYPT, + plaintext, + plaintext_len, + NULL, + 0, + ciphertext, + ciphertext_len, + &encrypt_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); +#ifdef SOC_CCOMP_TIMER_SUPPORTED + public_perf = ccomp_timer_stop(); +#endif // SOC_CCOMP_TIMER_SUPPORTED + + size_t decrypt_len = 0; +#ifdef SOC_CCOMP_TIMER_SUPPORTED + ccomp_timer_start(); +#endif + // Decrypt the ciphertext + status = psa_asymmetric_decrypt(key_id, + PSA_ALG_RSA_PKCS1V15_CRYPT, + ciphertext, + encrypt_len, + NULL, + 0, + decrypted, + decrypted_len, + &decrypt_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + #ifdef SOC_CCOMP_TIMER_SUPPORTED + private_perf = ccomp_timer_stop(); + #endif // SOC_CCOMP_TIMER_SUPPORTED + + // Verify decrypted data matches original plaintext + TEST_ASSERT_EQUAL(plaintext_len, decrypt_len); + + #ifdef SOC_CCOMP_TIMER_SUPPORTED + printf("RSA Key Size: %d bits\n", (keysize == PSA_RSA_KEY_SIZE_2048) ? 2048 : + (keysize == PSA_RSA_KEY_SIZE_3072) ? 3072 : 4096); + printf("Encryption took %d us, Decryption took %d us\n", public_perf, private_perf); + + if (keysize == PSA_RSA_KEY_SIZE_2048) { + TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_2048KEY_PUBLIC_OP, "%d us", public_perf); + TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_2048KEY_PRIVATE_OP, "%d us", private_perf); + } else if (keysize == 4096) { + TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_4096KEY_PUBLIC_OP, "%d us", public_perf); + TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_4096KEY_PRIVATE_OP, "%d us", private_perf); + } + #endif // SOC_CCOMP_TIMER_SUPPORTED + psa_destroy_key(key_id); + keysize++; + } +} diff --git a/components/mbedtls/test_apps/main/test_rsa.c b/components/mbedtls/test_apps/main/test_rsa.c deleted file mode 100644 index 457caaa45d6..00000000000 --- a/components/mbedtls/test_apps/main/test_rsa.c +++ /dev/null @@ -1,611 +0,0 @@ -/* mbedTLS RSA functionality tests - * - * Focus on testing functionality where we use ESP32 hardware - * accelerated crypto features - * - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include "esp_system.h" -#include "esp_task_wdt.h" -#include "mbedtls/rsa.h" -#include "mbedtls/pk.h" -#include "mbedtls/x509_crt.h" -#include -#include -#include "entropy_poll.h" -#include "freertos/FreeRTOS.h" -#include "unity.h" -#include "test_utils.h" -#include "memory_checks.h" -#include "ccomp_timer.h" - -#define PRINT_DEBUG_INFO - -/* Taken from openssl s_client -connect api.gigafive.com:443 -showcerts - */ -static const char *rsa4096_cert = "-----BEGIN CERTIFICATE-----\n"\ - "MIIExzCCA6+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBkjELMAkGA1UEBhMCVVMx\n"\ - "CzAJBgNVBAgMAkNBMRQwEgYDVQQHDAtTYW50YSBDbGFyYTElMCMGA1UECgwcR2ln\n"\ - "YWZpdmUgVGVjaG5vbG9neSBQYXJ0bmVyczEZMBcGA1UEAwwQR2lnYWZpdmUgUm9v\n"\ - "dCBDQTEeMBwGCSqGSIb3DQEJARYPY2FAZ2lnYWZpdmUuY29tMB4XDTE2MDgyNzE2\n"\ - "NDYyM1oXDTI2MDgyNTE2NDYyM1owgZcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD\n"\ - "QTEUMBIGA1UEBwwLU2FudGEgQ2xhcmExKTAnBgNVBAoMIEdpZ2FmaXZlIFRlY2hu\n"\ - "b2xvZ3kgUGFydG5lcnMgTExDMRkwFwYDVQQDDBBhcGkuZ2lnYWZpdmUuY29tMR8w\n"\ - "HQYJKoZIhvcNAQkBFhBjcmxAZ2lnYWZpdmUuY29tMIICIjANBgkqhkiG9w0BAQEF\n"\ - "AAOCAg8AMIICCgKCAgEAof82VrEpXMpsI/ddW6RLeTeSYtxiXZZkRbDKN6otYgEk\n"\ - "vA8yRbzei2cO2A/8+Erhe9beYLAMXWF+bjoUAFwnuIcbmufgHprOYzX/7CYXCsrH\n"\ - "LrJfVF6kvjCXy2W3xSvgh8ZgHNWnBGzl13tq19Fz8x0AhK5GQ9608oJCbnQjpVSI\n"\ - "lZDl3JVOifCeXf2c7nMhVOC/reTeto0Gbchs8Ox50WyojmfYbVjOQcA7f8p1eI+D\n"\ - "XUJK01cUGVu6/KarVArGHh5LsiyXOadbyeyOXPmjyrgarG3IIBeQSNECfJZPc/OW\n"\ - "lFszjU4YLDckI4x+tReiuFQbQPN5sDplcEldmZZm/8XD36ddvAaDds+SYlPXxDK7\n"\ - "7L8RBVUG2Ylc9YZf7RE6IMDmdQmsCZDX0VxySYEmzv5lnAx4mzzaXcgS+kHMOLyK\n"\ - "n9UxmpzwQoqqC9tMZqwRaeKW1njR1dSwQLqirBPfGCWKkpkpm7C3HEfeeLrasral\n"\ - "aPf6LAwN3A4ZKHa5Jmne7W+1eYS1aTXOAOLIPcXRAh1B80H+SusIdM9d6vk2YTIg\n"\ - "khwGQV3sgM6nIO5+T/8z141UEjWbtP7pb/u0+G9Cg7TwvRoO2UukxdvOwNto1G2e\n"\ - "J3rKB/JSYsYWnPHvvh9XR+55PZ4iCf9Rqw/IP82uyGipR9gxlHqN8WhMTj9tNEkC\n"\ - "AwEAAaMhMB8wHQYDVR0OBBYEFISCemcSriz1HFhRXluw9H+Bv9lEMA0GCSqGSIb3\n"\ - "DQEBCwUAA4IBAQCMetK0xe6Y/uZpb1ARh+hHYcHI3xI+IG4opWJeoB1gDh/xpNAW\n"\ - "j6t5MGbLoqNMBXbqL26hnKVspyvCxw7ebI5ZJgjtbrD1t+0D8yrgIZzr7AWGA9Hj\n"\ - "WIHqDHGDxwkmfjVVPmuO3l5RtJmL6KV6kVL2bOvVI6gECpFLddmOTtg+iXDfSw3x\n"\ - "0+ueMYKr8QLF+TCxfzQTHvTHvOJtcZHecc1n7PYbRmI2p7tV6RoBpV69oM6NAVUV\n"\ - "i2QoSxm0pYzDzavOaxwhEPHT34Tpg6fwXy1QokFD9OtxRFtdpTjL3bMWpatZE+ba\n"\ - "cjvvf0utMW5fNjTTxu1nnpuxZM3ifTCqZJ+9\n"\ - "-----END CERTIFICATE-----\n"; - -static const char *rsa3072_cert = "-----BEGIN CERTIFICATE-----\n"\ - "MIIEszCCAxugAwIBAgIUNTBsyv59/rRarOVm3KBA29zqEtUwDQYJKoZIhvcNAQEL\n"\ - "BQAwaTELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFNoYW5naGFpMREwDwYDVQQHDAhT\n"\ - "aGFuZ2hhaTESMBAGA1UECgwJRXNwcmVzc2lmMQwwCgYDVQQLDANJREYxEjAQBgNV\n"\ - "BAMMCWVzcHJlc3NpZjAeFw0yMDA3MTQwODQ5NDdaFw0yMTA3MTQwODQ5NDdaMGkx\n"\ - "CzAJBgNVBAYTAkNOMREwDwYDVQQIDAhTaGFuZ2hhaTERMA8GA1UEBwwIU2hhbmdo\n"\ - "YWkxEjAQBgNVBAoMCUVzcHJlc3NpZjEMMAoGA1UECwwDSURGMRIwEAYDVQQDDAll\n"\ - "c3ByZXNzaWYwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDMj3ZwPd2y\n"\ - "+UxzmMUdZC5I5JQIzvUmHRNJWUe99Vht/rIEQuNSGg7xjyvuZoyeFo+Yg+QYUICa\n"\ - "Ipe4y2bZS12QsTxUmeoEhYORDSeQXFEo4aUmWuKIs6Y41dBOL7eDYDL3FRmIgmcn\n"\ - "qMonyCrSzXlcgHOVtMd8U8ifkX5u+nTigQLSIHVeAFz8CvC0tIiPm9YFurtMN15p\n"\ - "P1K/AH17ljtwVqacrI/asZgX+ECY5rauNJLigEYgfr7+xV6GofaXp6rUpGgWbVxM\n"\ - "hqKe/dbDuIzte3VK+zRDNDCeE5gPQjgoSDblOVmPemrq7KKjZ/PKmP47ct5a/0Ov\n"\ - "zWcdCgaXDRoPiwbpmz3Z6uh3JdvsDf214svLK+z4EDIRzpvggM0pfDvOADatiPkr\n"\ - "KmnFD1ZZx3R29/7IZ5OVvQL1hgWbm3cL4JADOc8PQKcqCzBE9JDdAVoa228ESaJ/\n"\ - "n4b63qaqfgBnoaFzCEruEcXj5nuXBxlk19WWtgY1tZtAgoA8hTWxxH0CAwEAAaNT\n"\ - "MFEwHQYDVR0OBBYEFPlwrvgkde/r+F8VRMMtpDUIxAtgMB8GA1UdIwQYMBaAFPlw\n"\ - "rvgkde/r+F8VRMMtpDUIxAtgMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\n"\ - "BQADggGBAH9nBaEP+FWyaZnmxCblKhs8eIEYXzjxbnRUPo5b3uL/PAv1XD1kEUwY\n"\ - "GWnJ7Z5HOSCdVMgo1opmKGLWuiVP6Vlt9QuA/tWh0bGScL4QfriPXuA7aXAcLbW/\n"\ - "BqHNJ9Z+H2Fq09XktkZE4Nfnv3iTMMqfNCchM3t3iWZRf2sRVYIdd5OjhM+CLLUK\n"\ - "kYNiseAgbcBX0/kqTdHlC6OS8Mcu9btJ/663DZy8tndf+PH+EB6fexQd9T31jWoj\n"\ - "OkEkJ4vDRZP+0LceK7kNcMOcLx8DnF9LwUyHQitW7NMFServoTfxy8A0yep7nIOH\n"\ - "M/ndECzirQ6WkR9jMG3cw0Jm5mZvA9IAvnLhUO45AyZGC8mShJ0AaXtqejqPg9ng\n"\ - "//5VIpzoqwVkrMYlMA7ZrccQiRsd2nlBHr+64PRwRCp7y5FOxIzhGzsJibXUpO/V\n"\ - "FNwuPz+VcnPvJE7r4gB1oRViiGYojMDQV3G+jbgvpTHKUKP6zzavSAKs+FlfEAmh\n"\ - "EtmuT/beDA==\n"\ - "-----END CERTIFICATE-----\n"; - -/* Root cert from openssl s_client -connect google.com:443 -showcerts - */ -static const char *rsa2048_cert = "-----BEGIN CERTIFICATE-----\n"\ - "MIIFCzCCAvOgAwIBAgIQf/AFoHxM3tEArZ1mpRB7mDANBgkqhkiG9w0BAQsFADBH\n"\ - "MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\n"\ - "QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjMxMjEzMDkwMDAwWhcNMjkwMjIw\n"\ - "MTQwMDAwWjA7MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNl\n"\ - "cnZpY2VzMQwwCgYDVQQDEwNXUjIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n"\ - "AoIBAQCp/5x/RR5wqFOfytnlDd5GV1d9vI+aWqxG8YSau5HbyfsvAfuSCQAWXqAc\n"\ - "+MGr+XgvSszYhaLYWTwO0xj7sfUkDSbutltkdnwUxy96zqhMt/TZCPzfhyM1IKji\n"\ - "aeKMTj+xWfpgoh6zySBTGYLKNlNtYE3pAJH8do1cCA8Kwtzxc2vFE24KT3rC8gIc\n"\ - "LrRjg9ox9i11MLL7q8Ju26nADrn5Z9TDJVd06wW06Y613ijNzHoU5HEDy01hLmFX\n"\ - "xRmpC5iEGuh5KdmyjS//V2pm4M6rlagplmNwEmceOuHbsCFx13ye/aoXbv4r+zgX\n"\ - "FNFmp6+atXDMyGOBOozAKql2N87jAgMBAAGjgf4wgfswDgYDVR0PAQH/BAQDAgGG\n"\ - "MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/\n"\ - "AgEAMB0GA1UdDgQWBBTeGx7teRXUPjckwyG77DQ5bUKyMDAfBgNVHSMEGDAWgBTk\n"\ - "rysmcRorSCeFL1JmLO/wiRNxPjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAKG\n"\ - "GGh0dHA6Ly9pLnBraS5nb29nL3IxLmNydDArBgNVHR8EJDAiMCCgHqAchhpodHRw\n"\ - "Oi8vYy5wa2kuZ29vZy9yL3IxLmNybDATBgNVHSAEDDAKMAgGBmeBDAECATANBgkq\n"\ - "hkiG9w0BAQsFAAOCAgEARXWL5R87RBOWGqtY8TXJbz3S0DNKhjO6V1FP7sQ02hYS\n"\ - "TL8Tnw3UVOlIecAwPJQl8hr0ujKUtjNyC4XuCRElNJThb0Lbgpt7fyqaqf9/qdLe\n"\ - "SiDLs/sDA7j4BwXaWZIvGEaYzq9yviQmsR4ATb0IrZNBRAq7x9UBhb+TV+PfdBJT\n"\ - "DhEl05vc3ssnbrPCuTNiOcLgNeFbpwkuGcuRKnZc8d/KI4RApW//mkHgte8y0YWu\n"\ - "ryUJ8GLFbsLIbjL9uNrizkqRSvOFVU6xddZIMy9vhNkSXJ/UcZhjJY1pXAprffJB\n"\ - "vei7j+Qi151lRehMCofa6WBmiA4fx+FOVsV2/7R6V2nyAiIJJkEd2nSi5SnzxJrl\n"\ - "Xdaqev3htytmOPvoKWa676ATL/hzfvDaQBEcXd2Ppvy+275W+DKcH0FBbX62xevG\n"\ - "iza3F4ydzxl6NJ8hk8R+dDXSqv1MbRT1ybB5W0k8878XSOjvmiYTDIfyc9acxVJr\n"\ - "Y/cykHipa+te1pOhv7wYPYtZ9orGBV5SGOJm4NrB3K1aJar0RfzxC3ikr7Dyc6Qw\n"\ - "qDTBU39CluVIQeuQRgwG3MuSxl7zRERDRilGoKb8uY45JzmxWuKxrfwT/478JuHU\n"\ - "/oTxUFqOl2stKnn7QGTq8z29W+GgBLCXSBxC9epaHM0myFH/FJlniXJfHeytWt0=\n"\ - "-----END CERTIFICATE-----\n"; - - -/* Some random input bytes to public key encrypt */ -static const uint8_t pki_input[4096/8] = { - 0, 1, 4, 6, 7, 9, 33, 103, 49, 11, 56, 211, 67, 92 }; - -/* Result of an RSA4096 operation using cert's public key - (raw PKI, no padding/etc) */ -static const uint8_t pki_rsa4096_output[] = { - 0x91, 0x87, 0xcd, 0x04, 0x80, 0x7c, 0x8b, 0x0b, - 0x0c, 0xc0, 0x38, 0x37, 0x7a, 0xe3, 0x2c, 0x94, - 0xea, 0xc4, 0xcb, 0x83, 0x2c, 0x77, 0x71, 0x14, - 0x11, 0x85, 0x16, 0x61, 0xd3, 0x64, 0x2a, 0x0f, - 0xf9, 0x6b, 0x45, 0x04, 0x66, 0x5d, 0x15, 0xf1, - 0xcf, 0x69, 0x77, 0x90, 0xb9, 0x41, 0x68, 0xa9, - 0xa6, 0xfd, 0x94, 0xdc, 0x6a, 0xce, 0xc7, 0xb6, - 0x41, 0xd9, 0x44, 0x3c, 0x02, 0xb6, 0xc7, 0x26, - 0xce, 0xec, 0x66, 0x21, 0xa8, 0xe8, 0xf4, 0xa9, - 0x33, 0x4a, 0x6c, 0x28, 0x0f, 0x50, 0x30, 0x32, - 0x28, 0x00, 0xbb, 0x2c, 0xc3, 0x44, 0x72, 0x31, - 0x93, 0xd4, 0xde, 0x29, 0x6b, 0xfa, 0x31, 0xfd, - 0x3a, 0x05, 0xc6, 0xb1, 0x28, 0x43, 0x57, 0x20, - 0xf7, 0xf8, 0x13, 0x0c, 0x4a, 0x80, 0x00, 0xab, - 0x1f, 0xe8, 0x88, 0xad, 0x56, 0xf2, 0xda, 0x5a, - 0x50, 0xe9, 0x02, 0x09, 0x21, 0x2a, 0xfc, 0x82, - 0x68, 0x34, 0xf9, 0x04, 0xa3, 0x25, 0xe1, 0x0f, - 0xa8, 0x77, 0x29, 0x94, 0xb6, 0x9d, 0x5a, 0x08, - 0x33, 0x8d, 0x27, 0x6a, 0xc0, 0x3b, 0xad, 0x91, - 0x8a, 0x83, 0xa9, 0x2e, 0x48, 0xcd, 0x67, 0xa3, - 0x3a, 0x35, 0x41, 0x85, 0xfa, 0x3f, 0x61, 0x1f, - 0x80, 0xeb, 0xcd, 0x5a, 0xc5, 0x14, 0x7b, 0xab, - 0x9c, 0x45, 0x11, 0xd2, 0x25, 0x9a, 0x16, 0xeb, - 0x9c, 0xfa, 0xbe, 0x73, 0x18, 0xbd, 0x25, 0x8e, - 0x99, 0x6d, 0xb3, 0xbc, 0xac, 0x2d, 0xa2, 0x53, - 0xe8, 0x7c, 0x38, 0x1b, 0x7a, 0x75, 0xff, 0x76, - 0x4f, 0x48, 0x5b, 0x39, 0x20, 0x5a, 0x7b, 0x82, - 0xd3, 0x33, 0x33, 0x2a, 0xab, 0x6a, 0x7a, 0x42, - 0x1d, 0x1f, 0xd1, 0x61, 0x58, 0xd7, 0x38, 0x52, - 0xdf, 0xb0, 0x61, 0x98, 0x63, 0xb7, 0xa1, 0x4e, - 0xdb, 0x9b, 0xcb, 0xb7, 0x85, 0xc4, 0x3e, 0x03, - 0xe5, 0x59, 0x50, 0x28, 0x5a, 0x4d, 0x7f, 0x53, - 0x2e, 0x99, 0x1d, 0x6d, 0x85, 0x27, 0x78, 0x34, - 0x5e, 0xae, 0xc9, 0x1b, 0x37, 0x96, 0xde, 0x40, - 0x87, 0x35, 0x3c, 0x1f, 0xe0, 0x8f, 0xfb, 0x3a, - 0x58, 0x0e, 0x60, 0xe9, 0x06, 0xbd, 0x83, 0x03, - 0x92, 0xde, 0x5e, 0x69, 0x28, 0xb1, 0x00, 0xeb, - 0x44, 0xca, 0x3c, 0x49, 0x03, 0x10, 0xa8, 0x84, - 0xa6, 0xbb, 0xd5, 0xda, 0x98, 0x8c, 0x6f, 0xa3, - 0x0f, 0x39, 0xf3, 0xa7, 0x7d, 0xd5, 0x3b, 0xe2, - 0x85, 0x12, 0xda, 0xa4, 0x4d, 0x80, 0x97, 0xcb, - 0x11, 0xe0, 0x89, 0x90, 0xff, 0x5b, 0x72, 0x19, - 0x59, 0xd1, 0x39, 0x23, 0x9f, 0xb0, 0x00, 0xe2, - 0x45, 0x72, 0xc6, 0x9a, 0xbc, 0xe1, 0xd1, 0x51, - 0x6b, 0x35, 0xd2, 0x49, 0xbf, 0xb6, 0xfe, 0xab, - 0x09, 0xf7, 0x9d, 0xa4, 0x6e, 0x69, 0xb6, 0xf9, - 0xde, 0xe3, 0x57, 0x0c, 0x1a, 0x96, 0xf1, 0xcc, - 0x1c, 0x92, 0xdb, 0x44, 0xf4, 0x45, 0xfa, 0x8f, - 0x87, 0xcf, 0xf4, 0xd2, 0xa1, 0xf8, 0x69, 0x18, - 0xcf, 0xdc, 0xa0, 0x1f, 0xb0, 0x26, 0xad, 0x81, - 0xab, 0xdf, 0x78, 0x18, 0xa2, 0x74, 0xba, 0x2f, - 0xec, 0x70, 0xa2, 0x1f, 0x56, 0xee, 0xff, 0xc9, - 0xfe, 0xb1, 0xe1, 0x9b, 0xea, 0x0e, 0x33, 0x14, - 0x5f, 0x6e, 0xca, 0xee, 0x02, 0x56, 0x5a, 0x67, - 0x42, 0x9a, 0xbf, 0x55, 0xc0, 0x0f, 0x8e, 0x01, - 0x67, 0x63, 0x6e, 0xd1, 0x57, 0xf7, 0xf1, 0xc6, - 0x92, 0x9e, 0xb5, 0x45, 0xe1, 0x50, 0x58, 0x94, - 0x20, 0x90, 0x6a, 0x29, 0x2d, 0x4b, 0xd1, 0xb5, - 0x68, 0x63, 0xb5, 0xe6, 0xd8, 0x6e, 0x84, 0x80, - 0xad, 0xe6, 0x03, 0x1e, 0x51, 0xc2, 0xa8, 0x6d, - 0x84, 0xec, 0x2d, 0x7c, 0x61, 0x02, 0xd1, 0xda, - 0xf5, 0x94, 0xfa, 0x2d, 0xa6, 0xed, 0x89, 0x6a, - 0x6a, 0xda, 0x07, 0x5d, 0x83, 0xfc, 0x43, 0x76, - 0x7c, 0xca, 0x8c, 0x00, 0xfc, 0xb9, 0x2c, 0x23, -}; - -static const uint8_t pki_rsa3072_output[] = { - 0x86, 0xc0, 0xe4, 0xa5, 0x4b, 0x45, 0xe4, 0xd4, 0x0f, 0xb7, 0xe3, 0x10, 0x4f, 0xea, 0x88, 0x91, - 0x3d, 0xad, 0x43, 0x86, 0x90, 0xf0, 0xd8, 0xf0, 0x29, 0x21, 0xc7, 0x5c, 0x75, 0x49, 0x91, 0xce, - 0xf8, 0x34, 0x91, 0xbd, 0x89, 0x61, 0xcf, 0x47, 0x0e, 0x4d, 0x3f, 0x29, 0xd1, 0x02, 0xa7, 0xa8, - 0x8f, 0x6a, 0xda, 0x1a, 0xf2, 0xf1, 0x18, 0x92, 0x35, 0xf6, 0x0c, 0x07, 0x5a, 0x84, 0xfa, 0x65, - 0xd3, 0x02, 0xe0, 0x53, 0x17, 0x5d, 0xf7, 0x45, 0x26, 0xcc, 0xf9, 0x26, 0xf5, 0x6a, 0x66, 0xbb, - 0xef, 0x33, 0xcb, 0x03, 0x6e, 0x6a, 0x93, 0x6c, 0x2a, 0x27, 0xa7, 0xf7, 0x2c, 0xdc, 0x00, 0xdd, - 0x98, 0x52, 0xfb, 0xce, 0x31, 0xe2, 0x96, 0x20, 0x98, 0x0a, 0xf4, 0x19, 0x0f, 0xbf, 0x22, 0xed, - 0x37, 0xb2, 0x14, 0x10, 0x88, 0xa3, 0x6a, 0x43, 0x26, 0xb8, 0x54, 0xf1, 0xb8, 0xc6, 0x56, 0xb7, - 0x89, 0x34, 0xc0, 0xba, 0xae, 0x38, 0x35, 0x2c, 0x13, 0x57, 0x7a, 0xa4, 0x4b, 0xf2, 0x21, 0x82, - 0xf4, 0xea, 0x1a, 0x2c, 0xd8, 0x32, 0xe8, 0x5f, 0x37, 0x04, 0x52, 0x3d, 0xff, 0xc2, 0x85, 0x00, - 0xd2, 0x8d, 0x84, 0x36, 0x61, 0x61, 0x7b, 0xea, 0x7c, 0x3d, 0xeb, 0x51, 0xea, 0xf2, 0x67, 0xc9, - 0xb8, 0xa6, 0x98, 0x54, 0x3f, 0x5b, 0x8f, 0x1a, 0x8a, 0x93, 0x81, 0x05, 0xa3, 0x15, 0xf8, 0x54, - 0x8f, 0x75, 0xe2, 0x01, 0xc3, 0x47, 0xc3, 0x8f, 0xc7, 0x6d, 0x04, 0xbc, 0x05, 0x88, 0xd9, 0x62, - 0xcc, 0x14, 0xea, 0x30, 0x68, 0x73, 0xd5, 0xe5, 0x53, 0x7c, 0xb1, 0xa0, 0xe5, 0x6c, 0xd0, 0xa3, - 0x07, 0x2a, 0x5e, 0x2a, 0x0f, 0x89, 0x39, 0xea, 0xf9, 0xf5, 0xfb, 0x3b, 0xee, 0x66, 0xd9, 0xd4, - 0x04, 0x2d, 0x1b, 0xc9, 0xc2, 0x37, 0xc8, 0xa8, 0x71, 0xea, 0xa8, 0xf6, 0xe6, 0xc1, 0xdc, 0x5b, - 0x70, 0x68, 0x89, 0xa5, 0x69, 0xc0, 0x7f, 0x15, 0x8b, 0x6d, 0xc6, 0x88, 0x41, 0x8b, 0x25, 0x8f, - 0x2f, 0x5c, 0x81, 0x94, 0x1b, 0x8c, 0x52, 0x3f, 0xe5, 0x97, 0x6d, 0x4a, 0xc6, 0x42, 0x35, 0x0e, - 0x59, 0xce, 0x00, 0x3c, 0x2b, 0x0f, 0x5a, 0xc5, 0x1b, 0x01, 0xf3, 0x02, 0x70, 0xb1, 0x88, 0xda, - 0x7b, 0x5b, 0x4d, 0x3e, 0xd1, 0x15, 0x57, 0xc8, 0x39, 0x14, 0xff, 0x8d, 0x2b, 0x12, 0xf5, 0x5b, - 0xaf, 0x78, 0x2e, 0x0b, 0xcd, 0x27, 0x83, 0xdb, 0x4e, 0xe1, 0x5d, 0xa5, 0xbd, 0xfe, 0x2b, 0x6e, - 0x8b, 0x54, 0x7d, 0x14, 0x6f, 0x4d, 0xe1, 0x14, 0xc8, 0x30, 0x0e, 0x10, 0x23, 0x2a, 0xe1, 0xe5, - 0xee, 0xa3, 0x69, 0x8d, 0xe2, 0x9a, 0xed, 0x0c, 0x23, 0x16, 0x8e, 0x95, 0xae, 0x1a, 0xa2, 0x28, - 0x61, 0x25, 0xa2, 0x15, 0x74, 0xc4, 0xec, 0x6b, 0x73, 0xb2, 0x8c, 0xd2, 0x64, 0xfd, 0x2b, 0x92, -}; - -static const uint8_t pki_rsa2048_output[] = { - 0x3c, 0xd6, 0xc2, 0xbf, 0x01, 0x4a, 0x00, 0x95, - 0x2c, 0x32, 0x11, 0xc0, 0xc9, 0x7e, 0x8f, 0x0a, - 0x15, 0xee, 0xfb, 0x34, 0x1d, 0xaa, 0xae, 0x15, - 0x11, 0x6d, 0x99, 0x2b, 0x09, 0xeb, 0x3f, 0x89, - 0x46, 0x98, 0x08, 0x2f, 0x10, 0x13, 0xa1, 0x17, - 0xc7, 0xec, 0x67, 0x3a, 0x34, 0x4f, 0x40, 0xcd, - 0xe2, 0xc0, 0xbe, 0x99, 0xc7, 0xe7, 0xff, 0xea, - 0xd0, 0x82, 0xd2, 0x62, 0x73, 0xde, 0x56, 0xe8, - 0xb6, 0xa7, 0xe7, 0xe1, 0x64, 0x90, 0x00, 0x56, - 0x1d, 0x2c, 0x1c, 0xc5, 0xec, 0x7f, 0xb1, 0x87, - 0x59, 0xb1, 0xd6, 0x44, 0x0f, 0x67, 0x35, 0xb4, - 0x91, 0x49, 0xed, 0x10, 0x4c, 0xef, 0xe5, 0xc8, - 0xea, 0x0d, 0xbd, 0xaf, 0xb9, 0xad, 0x12, 0x41, - 0xaa, 0xf4, 0x68, 0x54, 0x08, 0xec, 0x70, 0x8c, - 0xac, 0x6b, 0x57, 0xcf, 0x0a, 0x0c, 0x08, 0x34, - 0x28, 0x29, 0x27, 0xa4, 0x71, 0x80, 0x43, 0x59, - 0xd9, 0x35, 0x88, 0x28, 0x1d, 0xfa, 0x0b, 0x72, - 0xa0, 0xe1, 0x03, 0x65, 0x7a, 0xf8, 0x1c, 0x76, - 0x9a, 0xad, 0x21, 0x23, 0x11, 0x2f, 0x45, 0x40, - 0x72, 0x05, 0x69, 0x1b, 0x2a, 0x74, 0x9f, 0x95, - 0x44, 0x60, 0x05, 0x6a, 0x17, 0x80, 0x4a, 0xa0, - 0xed, 0x23, 0xa6, 0xef, 0x79, 0x5d, 0x83, 0xd8, - 0x8d, 0xd8, 0xe1, 0x4c, 0x5e, 0xf8, 0xfa, 0x11, - 0x57, 0xbe, 0xca, 0x22, 0x93, 0x5b, 0xe6, 0x8b, - 0xe1, 0x31, 0xde, 0x70, 0x80, 0x4a, 0xa2, 0xd3, - 0x91, 0xe8, 0xde, 0x88, 0xa2, 0x98, 0x73, 0x49, - 0x0d, 0x26, 0xe1, 0x42, 0xd7, 0xb9, 0x5e, 0xf6, - 0x05, 0x09, 0x27, 0xc6, 0x8c, 0xc2, 0xb1, 0x53, - 0x5f, 0x19, 0xaf, 0x2b, 0xfe, 0xac, 0x6a, 0x27, - 0xde, 0x89, 0xbc, 0x72, 0x3e, 0xd5, 0x9f, 0x36, - 0xc2, 0x91, 0x68, 0x30, 0xe7, 0x76, 0x96, 0x56, - 0x8f, 0x01, 0xc4, 0x5b, 0xb7, 0xb3, 0x90, 0x7f, -}; - -#ifdef CONFIG_MBEDTLS_HARDWARE_MPI -/* Pregenerated RSA 4096 size keys using openssl */ -static const char privkey_4096_buf[] = "-----BEGIN RSA PRIVATE KEY-----\n" - "MIIJKAIBAAKCAgEA1blr9wfIzTylroJHxcoq+YFA765gF5vj9b6tfaPG0XQExSkjndHv5sra4ar7T+k2sBB4OcKKeGHkNk6wk8tGmOS79r2L74XZs1eB0UruG+huV7Sd+YiWzwN8y9jGImA9hIkf1qxIvkco5WTmT7cVwUnCQ7qiiVadD/LgyeGD04yKZpzv9UJzfjXz5ITTn/ejcn7423M9qz41nhRWwK4zw1jv7IB57d1dWOCbN3RO4dvfVndCz8DOmLzJrZAkLsz39vppbIwbMqTXKFxWqzZY2xrYmnMx9p3v4hLeju7ls3fsekESonoP0C76u50wJfZWO2XcIUo4pue/jHi2o9KouhLXW/vyasplXvE6FFrBjSpsm1Nar4KQMUolEkUbO9baGcQvH9G5WOH0kwPt7AOSqM2EUPvBd7Jv0tbMI/BRZVVltC/t6WhannCM/I6nZrlNe5tie/qYlFu474jp5/tpa8RykkDxwl9whejIqd4iQbvDiP/GXgBYtDJ9VU/S2KqHJhQFLDi+F3+ewOcF391fgt1e1J2vNYLKZOfxTOl/1vJbU/2IjRWTRQ7cXnmpR/GNCRfgH2as6Z/0oknBSVephguDnO5QlveP4Cx2EOVY/A/KgDpu8PumSrlIk+YQgLxdKsXaVI6eDY4rY7q2uCJH3yIAfZJXEeD+ResUuSZltvECAwEAAQKCAgBwR89+oipOGHR6b5tBP+q/1bXFtXhqLs3eBuSiQu5qj2cKJYi+mtJMD3paYDdTThQa/ywKPDf+8n6wQTrnCj32iQRupjnkBg/O9kQPLixVoRCHJy5vL+D6tLxVY3cEDEeFX3zIjQ5SWJQVn6KXcnoNZ7CVYHGPcV9mR5TsuntFImp7aituUBDY14NgJKABRFosBqS6tZpKYo5MlCbXZy1ujUTOnNhxrIAj9yvUQFhIs/hrNpB1ELf46gWSF03LAIesyvWjvx9yxcL7QzeNDyozQbFVwvsWsvaZcIxXzw4B8RjdSV5+2V2BY4z6D6SB7R50ahjxrEqC9PFe3PQmsL9OvFjV9idYwFOhxiWXGjIm3wwFFLOj3e0TShscj2Iw+Ghd3wApvSdBZxzdjap1NHC+Q6yYU+BnivxUHcopVPPM3rsLndyRC6zfrQw/OkOlAP3bNL1hRedPRmRDOz0V1ihEpgC1VfXx6XOu4eg8xWiJgWX+BGvT5GWjfQg2hB1Jm344r3l0eLhr25dO80GIac2QGT2+WmYkXcsQ3AiqAn2VF8UB5mU+Iyh96jmSFVVltGZgfp98yFYN63/7wB++lhVQmJZwbglutng1qjQBFslIULddIHiYvF+AVvkrO3Hc2zg8rT91tbE13k06A1zlNGcQuQKLax8e+2/BNjsZU2E4uQKCAQEA7L4obKWYRHgG6j1VEDRrQU8Vkm4L11B+ZD/rsEh3q7LbzViOPv+1dZ40jX2qYScWyaefI46bukJlk/mlNv4Dh3EnSFvHPCInDM3oImCYImwUx0hkbSRyRNwlwRwx81LJzIR84cCqpNWrXXcplomUSM62ea1E1vtNSZs9Bg2OLoWvFOTPgk/xDi6ezdb6JFiId6cARup/bmZ363mg8jCq0wpTLVdUGrezfMj4GpB1uQET5xqXleumQu/04cHPOfXwpV0ikIOId/ldY/PetiRd86B32aB2Xd4fHUpxHMY+63MFmL6SsqMQJMPubv+eIrOId4HhT+nXNFBZXolT5XG5NwKCAQEA5xvvccHNyCTL0AebxD6EihWnp0/Dd0DwXWxZw0Yhhc9xa/W/QtygB6kPb35oKGvCKdm4dWCIGln03dU5D6CMNkJlbkxpo8gybz34SJ/6OvU836rBLHZXE3Xiqbe5XkdMdarA7kTEhEUqekDXPxhws9dWh0YjtAnBPpm1GQppiykI2edkiIhRgju5ghe+/UjAjxrEgCKZeAODh46hwZHERRKQN2MFUOFcOVDq+2wTJem9r3h1uBQAiZn8PDyx0rlRkwH2dZSSauVW+I713N0JGucOV7FeMO0ebioqqckh0i91ZJNH//Io8Sp8WuBsU/vcP9jT+5BDkCbc71BRO/AFFwKCAQBj4a6oeA0QBhvUw9+ZoKQHv9f4GZnBU+KfZSCJFWn39NQrhMsu5S+n2gGOGJDDwHwqxB+uHsKxCMZWciM0WmMex6ytKJucUURscIsZxespyrPRiEdmjNPxHXiISt8AK9OcB+GwVVsphERygI35Rz5aoWv3VhUPJqNrBKXwYdO06Q3/ILIz5oprU1wIuER9BSU+ZiUFxnXRHEZIAN7Yj5Piyh5hqNCBHTQK17dlbcFdNokxHdUKmYth/l8wyFYnvA21lt+4XOY8x+aQ/xjde+ZvnSozlTGbVNWHxBqI61MsfzDDStQVrhpniIqWJh6PwXM4CIII9z2mgqfR7NqKmTptAoIBAQDTYQOigmZbFvyrayoXVi8XtTLAnv3jByxR5pY7OtvSbagJ3J1w5CYim4iYq39M6TKP4KkMApy5rWl/tFQabPeRcS0gsxc0TBmFEaMTme7fGgrxcFZ6+koubHZCUN5k0sWmIeWQiKlNaY2uf7vf49TBSMXFuGtTclCjlybCnnlmZMPJuhCDqFsUyNelm15+f5pPyWXM5NiFooEc7WIZj996Zb4uSo1EKruVWONzzqe814s9AOp60SCkuoiv97uVRxbLZNItPRSmXNktQmSx/CEl0AuYPYwvJ9HbZQncfTBH9ExlDyidernjyr4uyHGMZyJN614ICy0gncsZv9ZtAd1FAoIBAA4toGPU/VcKFmK92zgO05jsg5vJzw5xeoxRWKrLg7iby6Su6BuNgaVwfYWeZuOhnXakid7FvFXKH6x44o9gyFm5bKqFhaXDzAnxzqcLeM5V+gititOsstpZCbVOoKQOhgTHyxpFNVX3E/nB8EunydWyhQMxKme//NsRroFm1vWljQKyL3zER82AzyseEpEYZoB/6g0n5uF2lR7KllxeBlINsceQ8g3JkmJTdS1hoXcyUSsZ+EgrRbCykNB5aVC5G3/W1OSZsFHbbMrYHCMnaYKwMqLmOkb11o6nOrJJ4pgHj8CVcp2TNjfy3y0Ru6RZ42b0Q+3LktJBGu9r5d04FgI=\n" - "-----END RSA PRIVATE KEY-----"; - -static const char privkey_2048_buf[] = "-----BEGIN RSA PRIVATE KEY-----\r\n" - "MIIEowIBAAKCAQEA8N8hdkemvj6Tpk975/OWhv9BrTsCBCu+ZYfDb5VI7U2meKBg\r\n" - "3dAkyyhRlY3fNwSRzBUMCzsHjpgnsB40wxOgiwlB9n6PMhq0qUVKAdCpKwFztsKd\r\n" - "JJAsCUC+Zlwxn4RpH6ZnMl3a/njRYjuDyI32kucMP/lBRo7ks1798Gy/j+x1h5xA\r\n" - "vZSlFoEXKjCC6S1DWhALePuZnk4m/jGP6g+YfyJXSTqsenKa/DcWndfn/JoElZ0J\r\n" - "nhud8lBXwVe6mMheE1yqfL+VTU1nwg/TPNZrZsFz2sXig/RQCKt6LuSuzhRpsLp+\r\n" - "BdwqEs9xrwlhZnp7j4kQBomISd6kAxQfYVROHQIDAQABAoIBAHgtO4rB8QWWPyCJ\r\n" - "I670r7OnA2OkvzrJgHMzq2SuvPX4+gfRLMM+qDzcXugZIrdWhk+maJ3p07lnXNXY\r\n" - "HEcAMedstQaA2n0LKfwSX/xL2TtlvBABRVoKvI3ZSaXUdcW60KBD69ULUsoICZ/T\r\n" - "Rcr4WX+t20TH3bOQc7ayvEwKVgE95xIUpTH9asw8uOPvKxW2j5OLQgZuWrWyUDg0\r\n" - "MFh92PhWtw3i5zq6OpTTsFJeceKYV/VstIYjZ+FslmhjQxJbr+2DJRbpHXKceqy6\r\n" - "9yWlSV0EM7neFCHlDa2WPhK8we+6IvMiNVQKj46fHGYNBaW/ZSX7TiG5J0Uqj2e9\r\n" - "0MUGJ8ECgYEA+frJabhfzW5+JfGjTObeznJZE6fAOjFzaBIwFu8Kz2mIjYpQlwVK\r\n" - "EepMkv2KkrJuqS4GnI+Nkq7G0BAUyUj9tTJ3HQzvtJrxsnxVi99Yofx1s1P4YAnu\r\n" - "c8t3ElJoQ4BRoQIs/hIvyYn22IxllBHiGESrnPQ38D82xyXQgd6S8JkCgYEA9qww\r\n" - "j7jx6Xpy/D1Dq8Dvalm7pz3J+yHnti4w2cqZ67grUoyGnNPtciNDdfi4JzLiKkUu\r\n" - "SDS3DacvFpFyND0m8sbpMjnR8Rvhj+bfH8KcOAowD+YR/+6vSb/P/aBt6gYXcaBn\r\n" - "cjepx+sE81mnC7UrHb4TjG4hO5t3ZTc6X28gyCUCgYAMZn9lSisecrO5SCJUp0M4\r\n" - "NH3stq6XdGqIKBbQnG0J2u9WLh1PUIjbGKdRx1f/bPCGXe0gCRL5yse7/IA7d+51\r\n" - "9ZnpDAI8EE+bDgXkWWD5MB/alHjGstdsURSICSR47L2f4g6/T8GlGr3vAg/r53My\r\n" - "xv1IXOkFdu1NtbeBKbxaSQKBgENDmw5mAVmIcXiFAEICn4ahp4EoYT6g9T2BhQKu\r\n" - "s6BKnU2qUj7Lr5ETOp8dzqGpx3B9Yux/q3cGotmFmd3S2x8SzJ5MlAoqbyy9aRSR\r\n" - "DeZeKNL9CuV+YcA7lOz1ZWOOe7AZbHwB38NLPBNb3CheI769iTkfAuLtNvabw8go\r\n" - "VokdAoGBALyvBhW+Squ5tx8NOEgAisakhAVOnT6jcoeKy6FyjcvKaWagmCOCC7Gz\r\n" - "QB9Yf1tJ+3di+aLtWWdmU494iKJHBtPMhfrYltCpxHHQGlUc/GLPY3Z5bBYYYWpb\r\n" - "Wzw4ZvDraKlAs7a9CRwS5cpktk5ptK4rc5noSXkvV+yOT75zXat2\r\n" - "-----END RSA PRIVATE KEY-----\r\n"; - -static const char privkey_3072_buf[] = "-----BEGIN RSA PRIVATE KEY-----\r\n" - "MIIG4wIBAAKCAYEAoMPuYRnHVPP49qiPACIsYBLVuj8xH4XqAuXmurOyPPFfKSch\r\n" - "52dn97sXvfXQw6hj+iPBeMSzbSAompjx4mUHtwn2+EvyXjqUe8qtI0y12uzXgOr8\r\n" - "vdwNLJO1kTmUWxQIa/e6dZpiKcEYYZ6qWNUGVH9IiMB9HdIFLNIdCAAC+gsK+Q0w\r\n" - "OT2CwnGOoZ/PzOXHyfte9pJTDk6nQJDKVTBoOLgVcJoCLwctGf7VJ9YI9+YXJKvW\r\n" - "1ZYq8PXM8KAVE7KHN7KiskJxDLSR4xuplxdT//LIBJMRvxAEPYohe7QvejFjtQc6\r\n" - "WbEJxV/Y4vWHOb2PVGUHATNK2kQ7/N5HgEdxABgLrXQSkGfKKmWwoy/W5TVDS+qX\r\n" - "fR/7WeJa/2e2+ZZVSQtiXdrWSKdgEmVdmM43Aso5ppC2C5QBajHAw2MKMZwxLHbI\r\n" - "nhQJQMJdmRvXI8Kg/+WEgknxQLFWrRW4ss3wR+2KvZ0eynEuzHkQxtUAWB8xgNAH\r\n" - "Bch/tr+xq1g3DFNXAgMBAAECggGAFvaFiScWesLyb8D51AoNjpeCIb0+9gK5vzo5\r\n" - "b7eVIPFVJ1qolBYIGrGFnaOL8zaNOUB8NRTbkB3EzvhDrJPDu1hYB3VJpD330YrM\r\n" - "mjstypyD16049qGE3DYo/BpeX3gID+vtnTi1BsPHCMKSEGg1JEKeCLJ97JGAHbvR\r\n" - "W8AsrKyBH7vLhJGNqNpxhhJ+qwSzOd2G3e9en6+KYkWMMQjeCiP5JAFLiI4c2ha1\r\n" - "OaBv3YDnE1zcLdvqPErPwBsNh6e7QLYbEvQj5mZ84/kCbrwFy//+Bf7to0u6weOy\r\n" - "8E1HU8UKdJfWsKwh+5BGDnKs8qgVQWJdPJWy25PVgkzp0ZnSKzp2AddMCrI2YHRM\r\n" - "Q+G+9bET/D96y7/08EAobDdXCplcPeOVb8ETbQTNTrHJibUCB4fqkN8tR2ZZTQ1F\r\n" - "axhmHDThsVFqWk+629j8c6XOQbx2dvzb7YfLK06ShiBcD0V6E7VFXHzR+x/xA9ir\r\n" - "zUcgLt9zvzj9puxlkhtzBZKcF3nBAoHBANCtY4NDnFoO+QUS59iz9hsoPAe8+S+U\r\n" - "PkvMSN7iziUkiXbXjQsr0v/PLHCuuXRyARBORaI4moLxzbTA1l1C+gBulI29j9zH\r\n" - "GwNnl587u5VCpbzuzr5YwHtp85Y1la2/ti+x0Qaw5uoa8G2TqoU4V6SG0qwinQl2\r\n" - "9mdNZzVmIBMbE0tTTTzc+CRIPBl9lRQR3Ff3o6eUs6uPE6g1lGZR1ydb2MLBM/wV\r\n" - "NgUUf7L5h/s8abrRjS+dnPmtxNgrRZQe9wKBwQDFOQyBzD3xkBgTSFQkU8OgNZyW\r\n" - "gNYglE1vLA+wv49NVAErHfKzYf/yw3fkYLDo9JfTJ3KckU6J815VnPXJFNMvjr2J\r\n" - "ExXG2JSbZHeUBRgExLU0iFlhQaxbAhuJ6PDrkGy+1ZtsJxYCPpifyNwjkZ0QKQlf\r\n" - "n3SwTMXIp0wd80FXVSwKPSuWUlrhByBcJDVwdCIeD8Oi9DrmVe0E9fXDboY2HARb\r\n" - "cgrN3n9jnEF/asIsfaHg8EI2z/EVC+C1mHuZdqECgcA5d4ZwH65vHrB1NT+j7etY\r\n" - "jzv45ZG6CJkfRqLKvqsGj4lLsRCmgusYh3U1kuh/qOWiF+wVQIFMjkqX/IMMK+Wt\r\n" - "OMawQgPcSPind1/J+ikucawy25ET2l0nn4X1V8xgjOsfN1jY/t6YmdKcWo4bIekA\r\n" - "5iAeR2n3sUsqJ6bEjdtHZ61okQg0OqYbV8k1O+BSJpkHoKrw+4J/PGetaxPzGZam\r\n" - "wCRxfcNTKIQ34e1I3G8WQQzc5dh7xGv2VmRfI4uFvwECgcEAuNGAVfZ3KfNVjGRg\r\n" - "bXaNwYncBvIPN5KiigbpYUHyYY3SVnyHHvE8cFwa80plHrlvubGi5vQIfKAzC9m+\r\n" - "PsSkL1H9bgITizcU9BYPNQgc/QL1qJgJ4mkvwk1UT0Wa17WNIrx8HLr4Ffxg/IO3\r\n" - "QCHJ5QX/wbtlF32qbyHP49U8q0GmtqWiPglJHs2V1qMb7Rj3i+JL/F4RAB8PsXFo\r\n" - "8M6XOQfCUYuqckgKaudYPbZm5liJJYkhE8qD6qwp1SNi2GphAoHABjUL8DTHgBWn\r\n" - "sr9/XQyornm0sruHcwr7SmGqIJ/hZUUYd4UfDW76e8SjvhRQ7nkpR3f4+LEBCqaJ\r\n" - "LDJDhg+6AColwKaWRWV9M1GXHhVD4vaTM46JAvH9wbhmJDUORHq8viyHlwO9QKpK\r\n" - "iHE/MtcYb5QBGP5md5wc8LY1lcQazDsJMLlcYNk6ZICNWWrcc2loG4VeOERpHU02\r\n" - "6AsKaaMGqBp/T9wYwFPUzk1i+jWCu66xfCYKvEubNdxT/R5juXrd\r\n" - "-----END RSA PRIVATE KEY-----\r\n"; - -#endif - -_Static_assert(sizeof(pki_rsa2048_output) == 2048/8, "rsa2048 output is wrong size"); -_Static_assert(sizeof(pki_rsa3072_output) == 3072/8, "rsa3072 output is wrong size"); -_Static_assert(sizeof(pki_rsa4096_output) == 4096/8, "rsa4096 output is wrong size"); - -void mbedtls_mpi_printf(const char *name, const mbedtls_mpi *X); - - -static void test_cert(const char *cert, const uint8_t *expected_output, size_t output_len); - -TEST_CASE("mbedtls RSA4096 cert", "[mbedtls]") -{ - - test_cert(rsa4096_cert, pki_rsa4096_output, 4096/8); -} - -TEST_CASE("mbedtls RSA3072 cert", "[mbedtls]") -{ - - test_cert(rsa3072_cert, pki_rsa3072_output, 3072/8); -} - -TEST_CASE("mbedtls RSA2048 cert", "[mbedtls]") -{ - test_cert(rsa2048_cert, pki_rsa2048_output, 2048/8); -} - -static void test_cert(const char *cert, const uint8_t *expected_output, size_t output_len) -{ - mbedtls_x509_crt crt; - mbedtls_rsa_context *rsa; - char buf[output_len]; - int res; - - bzero(buf, output_len); - - mbedtls_x509_crt_init(&crt); - - TEST_ASSERT_EQUAL_HEX16_MESSAGE(0, - -mbedtls_x509_crt_parse(&crt, - (const uint8_t *)cert, - strlen(cert)+1), - "parse cert"); - - rsa = mbedtls_pk_rsa(crt.pk); - TEST_ASSERT_NOT_NULL(rsa); - - res = mbedtls_rsa_check_pubkey(rsa); - TEST_ASSERT_EQUAL_HEX16_MESSAGE(0, - -res, - "check cert pubkey"); - - mbedtls_x509_crt_info(buf, sizeof(buf), "", &crt); - puts(buf); - - res = mbedtls_rsa_public(rsa, pki_input, (uint8_t *)buf); - if (res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE + MBEDTLS_ERR_RSA_PUBLIC_FAILED) { - mbedtls_x509_crt_free(&crt); - TEST_IGNORE_MESSAGE("Hardware does not support this key length"); - } - - TEST_ASSERT_EQUAL_HEX16_MESSAGE(0, - -res, - "RSA PK operation"); - - /* - // Dump buffer for debugging - for(int i = 0; i < output_len; i++) { - printf("0x%02x, ", buf[i]); - } - printf("\n"); - */ - - TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_output, buf, output_len); - - mbedtls_x509_crt_free(&crt); -} - -#ifdef CONFIG_MBEDTLS_HARDWARE_MPI -static void rsa_key_operations(int keysize, bool check_performance, bool generate_new_rsa); - -static int myrand(void *rng_state, unsigned char *output, size_t len) -{ - size_t olen; - return mbedtls_hardware_poll(rng_state, output, len, &olen); -} - -#ifdef PRINT_DEBUG_INFO -static void print_rsa_details(mbedtls_rsa_context *rsa) -{ - mbedtls_mpi X[5]; - for (int i=0; i<5; ++i) { - mbedtls_mpi_init( &X[i] ); - } - - if (0 == mbedtls_rsa_export(rsa, &X[0], &X[1], &X[2], &X[3], &X[4])) { - for (int i=0; i<5; ++i) { - mbedtls_mpi_printf((char*)"N\0P\0Q\0D\0E" + 2*i, &X[i]); - mbedtls_mpi_free( &X[i] ); - } - } -} -#endif - -#if CONFIG_FREERTOS_SMP // IDF-5260 -TEST_CASE("test performance RSA key operations", "[bignum][timeout=60]") -#else -TEST_CASE("test performance RSA key operations", "[bignum]") -#endif -{ - /** NOTE: - * For ESP32-S3, CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is enabled - * by default; allocating a lock of 92 bytes, which is never freed. - * - * MR !18574 adds the MPI crypto lock for S3 increasing the leakage by - * 92 bytes. This caused the RSA UT to fail with a leakage more than - * 1024 bytes. - * - * The allocations made by ESP32-S2 (944 bytes) and ESP32-S3 are the same, - * except for the JTAG lock (92 + 944 > 1024). - */ - TEST_ESP_OK(test_utils_set_leak_level(1088, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); - for (int keysize = 2048; keysize <= SOC_RSA_MAX_BIT_LEN; keysize += 1024) { - rsa_key_operations(keysize, true, false); - } -} - -#if CONFIG_FREERTOS_SMP // IDF-5260 -TEST_CASE("test RSA-3072 calculations", "[bignum][timeout=60]") -#else -TEST_CASE("test RSA-3072 calculations", "[bignum]") -#endif -{ - // use pre-genrated keys to make the test run a bit faster - rsa_key_operations(3072, false, false); -} - -#if CONFIG_FREERTOS_SMP // IDF-5260 -TEST_CASE("test RSA-2048 calculations", "[bignum][timeout=60]") -#else -TEST_CASE("test RSA-2048 calculations", "[bignum]") -#endif -{ - // use pre-genrated keys to make the test run a bit faster - rsa_key_operations(2048, false, false); -} - -#if CONFIG_FREERTOS_SMP // IDF-5260 -TEST_CASE("test RSA-4096 calculations", "[bignum][timeout=60]") -#else -TEST_CASE("test RSA-4096 calculations", "[bignum]") -#endif -{ - // use pre-genrated keys to make the test run a bit faster - rsa_key_operations(4096, false, false); -} - - -static void rsa_key_operations(int keysize, bool check_performance, bool generate_new_rsa) -{ - mbedtls_pk_context clientkey; - mbedtls_rsa_context rsa; - unsigned char orig_buf[4096 / 8]; - unsigned char encrypted_buf[4096 / 8]; - unsigned char decrypted_buf[4096 / 8]; - int res = 0; - - printf("First, orig_buf is encrypted by the public key, and then decrypted by the private key\n"); - printf("keysize=%d check_performance=%d generate_new_rsa=%d\n", keysize, check_performance, generate_new_rsa); - - memset(orig_buf, 0xAA, sizeof(orig_buf)); - orig_buf[0] = 0; // Ensure that orig_buf is smaller than rsa.N - if (generate_new_rsa) { - mbedtls_rsa_init(&rsa); - TEST_ASSERT_EQUAL(0, mbedtls_rsa_gen_key(&rsa, myrand, NULL, keysize, 65537)); - } else { - mbedtls_pk_init(&clientkey); - - switch(keysize) { - case 4096: - res = mbedtls_pk_parse_key(&clientkey, (const uint8_t *)privkey_4096_buf, sizeof(privkey_4096_buf), NULL, 0, myrand, NULL); - break; - case 3072: - res = mbedtls_pk_parse_key(&clientkey, (const uint8_t *)privkey_3072_buf, sizeof(privkey_3072_buf), NULL, 0, myrand, NULL); - break; - case 2048: - res = mbedtls_pk_parse_key(&clientkey, (const uint8_t *)privkey_2048_buf, sizeof(privkey_2048_buf), NULL, 0, myrand, NULL); - break; - default: - TEST_FAIL_MESSAGE("unsupported keysize, pass generate_new_rsa=true or update test"); - } - - TEST_ASSERT_EQUAL_HEX16(0, -res); - - memcpy(&rsa, mbedtls_pk_rsa(clientkey), sizeof(mbedtls_rsa_context)); - } - -#ifdef PRINT_DEBUG_INFO - print_rsa_details(&rsa); -#endif - - TEST_ASSERT_EQUAL(keysize, (int)rsa.MBEDTLS_PRIVATE(len) * 8); - TEST_ASSERT_EQUAL(keysize, (int)rsa.MBEDTLS_PRIVATE(D).MBEDTLS_PRIVATE(n) * sizeof(mbedtls_mpi_uint) * 8); // The private exponent - -#ifdef SOC_CCOMP_TIMER_SUPPORTED - int public_perf, private_perf; - ccomp_timer_start(); - res = mbedtls_rsa_public(&rsa, orig_buf, encrypted_buf); - public_perf = ccomp_timer_stop(); - - if (res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE + MBEDTLS_ERR_RSA_PUBLIC_FAILED) { - mbedtls_rsa_free(&rsa); - TEST_IGNORE_MESSAGE("Hardware does not support this key length"); - } - TEST_ASSERT_EQUAL_HEX16(0, -res); - - ccomp_timer_start(); - res = mbedtls_rsa_private(&rsa, myrand, NULL, encrypted_buf, decrypted_buf); - private_perf = ccomp_timer_stop(); - TEST_ASSERT_EQUAL_HEX16(0, -res); - - if (check_performance && keysize == 2048) { - TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_2048KEY_PUBLIC_OP, "%d us", public_perf); - TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_2048KEY_PRIVATE_OP, "%d us", private_perf); - } else if (check_performance && keysize == 4096) { - TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_4096KEY_PUBLIC_OP, "%d us", public_perf); - TEST_PERFORMANCE_CCOMP_LESS_THAN(RSA_4096KEY_PRIVATE_OP, "%d us", private_perf); - } -#else - res = mbedtls_rsa_public(&rsa, orig_buf, encrypted_buf); - TEST_ASSERT_EQUAL_HEX16(0, -res); - res = mbedtls_rsa_private(&rsa, myrand, NULL, encrypted_buf, decrypted_buf); - TEST_ASSERT_EQUAL_HEX16(0, -res); - TEST_IGNORE_MESSAGE("Performance check skipped! (soc doesn't support ccomp timer)"); -#endif - - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(orig_buf, decrypted_buf, keysize / 8, "RSA operation"); - - mbedtls_rsa_free(&rsa); -} - - -TEST_CASE("mbedtls RSA Generate Key", "[mbedtls][timeout=60]") -{ - - mbedtls_rsa_context ctx; - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; - - const unsigned int key_size = 2048; - const int exponent = 65537; - -#if CONFIG_MBEDTLS_MPI_USE_INTERRUPT && CONFIG_ESP_TASK_WDT_EN && !CONFIG_ESP_TASK_WDT_INIT - /* Check that generating keys doesn't starve the watchdog if interrupt-based driver is used */ - esp_task_wdt_config_t twdt_config = { - .timeout_ms = 1000, - .idle_core_mask = (1 << 0), // Watch core 0 idle - .trigger_panic = true, - }; - TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_init(&twdt_config)); -#endif // CONFIG_MBEDTLS_MPI_USE_INTERRUPT && CONFIG_ESP_TASK_WDT_EN && !CONFIG_ESP_TASK_WDT_INIT - - mbedtls_rsa_init(&ctx); - mbedtls_ctr_drbg_init(&ctr_drbg); - - mbedtls_entropy_init(&entropy); - TEST_ASSERT_FALSE( mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) ); - - TEST_ASSERT_FALSE( mbedtls_rsa_gen_key(&ctx, mbedtls_ctr_drbg_random, &ctr_drbg, key_size, exponent) ); - - mbedtls_rsa_free(&ctx); - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); - -#if CONFIG_MBEDTLS_MPI_USE_INTERRUPT && CONFIG_ESP_TASK_WDT_EN && !CONFIG_ESP_TASK_WDT_INIT - TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit()); -#endif // CONFIG_MBEDTLS_MPI_USE_INTERRUPT && CONFIG_ESP_TASK_WDT_EN && !CONFIG_ESP_TASK_WDT_INIT - -} - -#endif // CONFIG_MBEDTLS_HARDWARE_MPI diff --git a/components/mbedtls/test_apps/main/test_sha.c b/components/mbedtls/test_apps/main/test_sha.c index fd6e660e164..5303d3b3cc7 100644 --- a/components/mbedtls/test_apps/main/test_sha.c +++ b/components/mbedtls/test_apps/main/test_sha.c @@ -16,256 +16,385 @@ #include "spi_flash_mmap.h" #include "soc/soc_caps.h" - +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "unity.h" #include "test_utils.h" -#include "mbedtls/sha1.h" -#include "mbedtls/sha256.h" - -#if SOC_SHA_SUPPORT_SHA512 -#include "mbedtls/sha512.h" -#endif #include "sha/sha_parallel_engine.h" - -/* Note: Most of the SHA functions are called as part of mbedTLS, so -are tested as part of mbedTLS tests. Only esp_sha() is different. -*/ - +#include "psa/crypto.h" +#include "mbedtls/md.h" #define TAG "sha_test" -#if SOC_SHA_SUPPORTED -TEST_CASE("Test esp_sha()", "[hw_crypto]") +// New test for PSA SHA-512 implementation +TEST_CASE("Test PSA SHA-512 with known test vectors", "[hw_crypto][psa]") { - const size_t BUFFER_SZ = 32 * 1024 + 6; // NB: not an exact multiple of SHA block size + ESP_LOGI(TAG, "Testing PSA SHA-512 implementation with known test vectors"); - int64_t elapsed; - uint32_t us_sha1; - uint8_t sha1_result[20] = { 0 }; + // Test Vector 1: SHA-512("abc") + // Expected: ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f + const unsigned char test1_input[] = "abc"; + const size_t test1_input_len = 3; + const unsigned char test1_expected[64] = { + 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f + }; -#if SOC_SHA_SUPPORT_SHA512 - uint32_t us_sha512; - uint8_t sha512_result[64] = { 0 }; -#endif + // Test Vector 2: SHA-512("") + // Expected: cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e + const unsigned char test2_input[] = ""; + const size_t test2_input_len = 0; + const unsigned char test2_expected[64] = { + 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, + 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, + 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, + 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e + }; - void *buffer = heap_caps_malloc(BUFFER_SZ, MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(buffer); - memset(buffer, 0xEE, BUFFER_SZ); + unsigned char psa_output[64]; + unsigned char mbedtls_output[64]; + size_t psa_output_len; + psa_status_t psa_status; + int mbedtls_ret; - const uint8_t sha1_expected[20] = { 0xc7, 0xbb, 0xd3, 0x74, 0xf2, 0xf6, 0x20, 0x86, - 0x61, 0xf4, 0x50, 0xd5, 0xf5, 0x18, 0x44, 0xcc, - 0x7a, 0xb7, 0xa5, 0x4a }; -#if SOC_SHA_SUPPORT_SHA512 - const uint8_t sha512_expected[64] = { 0xc7, 0x7f, 0xda, 0x8c, 0xb3, 0x58, 0x14, 0x8a, - 0x52, 0x3b, 0x46, 0x04, 0xc0, 0x85, 0xc5, 0xf0, - 0x46, 0x64, 0x14, 0xd5, 0x96, 0x7a, 0xa2, 0x80, - 0x20, 0x9c, 0x04, 0x27, 0x7d, 0x3b, 0xf9, 0x1f, - 0xb2, 0xa3, 0x45, 0x3c, 0xa1, 0x6a, 0x8d, 0xdd, - 0x35, 0x5e, 0x35, 0x57, 0x76, 0x22, 0x74, 0xd8, - 0x1e, 0x07, 0xc6, 0xa2, 0x9e, 0x3b, 0x65, 0x75, - 0x80, 0x7d, 0xe6, 0x6e, 0x47, 0x61, 0x2c, 0x94 }; -#endif + ESP_LOGI(TAG, "=== Test 1: SHA-512(\"abc\") ==="); - ccomp_timer_start(); - esp_sha(SHA1, buffer, BUFFER_SZ, sha1_result); - elapsed = ccomp_timer_stop(); - TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, sha1_result, sizeof(sha1_expected)); - us_sha1 = elapsed; - ESP_LOGI(TAG, "esp_sha() 32KB SHA1 in %" PRIu32 " us", us_sha1); + // Test with PSA + ESP_LOGI(TAG, "Testing PSA psa_hash_compute()..."); + psa_status = psa_hash_compute(PSA_ALG_SHA_512, test1_input, test1_input_len, + psa_output, sizeof(psa_output), &psa_output_len); + ESP_LOGI(TAG, "PSA status: 0x%x, output_len: %zu", (unsigned int)psa_status, psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(64, psa_output_len); -#if SOC_SHA_SUPPORT_SHA512 - ccomp_timer_start(); - esp_sha(SHA2_512, buffer, BUFFER_SZ, sha512_result); - elapsed = ccomp_timer_stop(); - TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_expected, sha512_result, sizeof(sha512_expected)); + ESP_LOGI(TAG, "PSA result: %02x %02x %02x %02x %02x %02x %02x %02x...", + psa_output[0], psa_output[1], psa_output[2], psa_output[3], + psa_output[4], psa_output[5], psa_output[6], psa_output[7]); + ESP_LOGI(TAG, "Expected result: %02x %02x %02x %02x %02x %02x %02x %02x...", + test1_expected[0], test1_expected[1], test1_expected[2], test1_expected[3], + test1_expected[4], test1_expected[5], test1_expected[6], test1_expected[7]); - us_sha512 = elapsed; - ESP_LOGI(TAG, "esp_sha() 32KB SHA512 in %" PRIu32 " us", us_sha512); -#endif + TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, psa_output, 64); + ESP_LOGI(TAG, "✓ PSA SHA-512(\"abc\") PASSED"); -/* NOTE: The Mbed TLS ROM implementation needs to updated to support SHA224 operations */ -#if !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL -#if SOC_SHA_SUPPORT_SHA224 - uint8_t sha224_result[28] = { 0 }; - const uint8_t sha224_expected[28] = { 0xc0, 0x2a, 0x54, 0x2f, 0x70, 0x93, 0xaa, 0x3e, - 0xb6, 0xec, 0xe6, 0xb2, 0xb8, 0xe6, 0x57, 0x27, - 0xf9, 0x34, 0x9e, 0xb7, 0xbc, 0x96, 0x0d, 0xf5, - 0xd9, 0x87, 0xa8, 0x17 }; - esp_sha(SHA2_224, buffer, BUFFER_SZ, sha224_result); - TEST_ASSERT_EQUAL_HEX8_ARRAY(sha224_expected, sha224_result, sizeof(sha224_expected)); -#endif -#endif + // Test with mbedtls_md + ESP_LOGI(TAG, "Testing mbedtls_md()..."); + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); + TEST_ASSERT_NOT_NULL(md_info); -#if SOC_SHA_SUPPORT_SHA384 - uint8_t sha384_result[48] = { 0 }; - const uint8_t sha384_expected[48] = { 0x72, 0x13, 0xc8, 0x09, 0x7b, 0xbc, 0x9e, 0x65, - 0x02, 0xf8, 0x1d, 0xd2, 0x02, 0xd3, 0xd1, 0x80, - 0x48, 0xb9, 0xfb, 0x10, 0x2f, 0x1b, 0xd1, 0x40, - 0x4c, 0xc6, 0x3c, 0xfe, 0xcf, 0xa0, 0x83, 0x1b, - 0x6e, 0xfb, 0x97, 0x17, 0x65, 0x08, 0x28, 0x04, - 0x2f, 0x06, 0x2c, 0x97, 0x4e, 0xf8, 0x26, 0x86 }; - esp_sha(SHA2_384, buffer, BUFFER_SZ, sha384_result); - TEST_ASSERT_EQUAL_HEX8_ARRAY(sha384_expected, sha384_result, sizeof(sha384_expected)); -#endif + mbedtls_ret = mbedtls_md(md_info, test1_input, test1_input_len, mbedtls_output); + ESP_LOGI(TAG, "mbedtls_md return: %d", mbedtls_ret); + TEST_ASSERT_EQUAL(0, mbedtls_ret); - free(buffer); + ESP_LOGI(TAG, "mbedtls result: %02x %02x %02x %02x %02x %02x %02x %02x...", + mbedtls_output[0], mbedtls_output[1], mbedtls_output[2], mbedtls_output[3], + mbedtls_output[4], mbedtls_output[5], mbedtls_output[6], mbedtls_output[7]); - TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA1_32KB, "%" PRId32 " us", us_sha1); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, mbedtls_output, 64); + ESP_LOGI(TAG, "✓ mbedtls_md SHA-512(\"abc\") PASSED"); -#if SOC_SHA_SUPPORT_SHA512 - TEST_PERFORMANCE_CCOMP_LESS_THAN(TIME_SHA512_32KB, "%" PRId32 " us", us_sha512); -#endif + // Verify both methods produce the same result + TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 64); + ESP_LOGI(TAG, "✓ PSA and mbedtls_md results match"); + + ESP_LOGI(TAG, "=== Test 2: SHA-512(\"\") (empty string) ==="); + + // Test with PSA + psa_status = psa_hash_compute(PSA_ALG_SHA_512, test2_input, test2_input_len, + psa_output, sizeof(psa_output), &psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(64, psa_output_len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, psa_output, 64); + ESP_LOGI(TAG, "✓ PSA SHA-512(\"\") PASSED"); + + // Test with mbedtls_md + mbedtls_ret = mbedtls_md(md_info, test2_input, test2_input_len, mbedtls_output); + TEST_ASSERT_EQUAL(0, mbedtls_ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, mbedtls_output, 64); + ESP_LOGI(TAG, "✓ mbedtls_md SHA-512(\"\") PASSED"); + + // Verify both methods produce the same result + TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 64); + ESP_LOGI(TAG, "✓ All PSA SHA-512 tests PASSED!"); } -/* NOTE: This test attempts to mmap 1MB of flash starting from address 0x00, which overlaps - * the entire TEE protected region, causing the mmap operation to fail and triggering an - * exception in the subsequent steps. - */ -#if !CONFIG_SECURE_ENABLE_TEE - -TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]") +TEST_CASE("Test PSA SHA-256 with known test vectors", "[hw_crypto][psa]") { - int r = -1; - const void* ptr; - spi_flash_mmap_handle_t handle; -#if CONFIG_MBEDTLS_SHA1_C - uint8_t sha1_espsha[20] = { 0 }; - uint8_t sha1_mbedtls[20] = { 0 }; -#endif - uint8_t sha256_espsha[32] = { 0 }; - uint8_t sha256_mbedtls[32] = { 0 }; + ESP_LOGI(TAG, "Testing PSA SHA-256 implementation with known test vectors"); -#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C - uint8_t sha512_espsha[64] = { 0 }; - uint8_t sha512_mbedtls[64] = { 0 }; -#endif + // Test Vector 1: SHA-256("abc") + // Expected: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad + const unsigned char test1_input[] = "abc"; + const size_t test1_input_len = 3; + const unsigned char test1_expected[32] = { + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad + }; - const size_t LEN = 1024 * 1024; + // Test Vector 2: SHA-256("") + // Expected: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + const unsigned char test2_input[] = ""; + const size_t test2_input_len = 0; + const unsigned char test2_expected[32] = { + 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, + 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, + 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, + 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 + }; - /* mmap() 1MB of flash, we don't care what it is really */ - esp_err_t err = spi_flash_mmap(0x0, LEN, SPI_FLASH_MMAP_DATA, &ptr, &handle); + // Test Vector 3: SHA-256("hello world") + // Expected: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 + const unsigned char test3_input[] = "hello world"; + const unsigned char test3_expected[32] = { + 0xb9, 0x4d, 0x27, 0xb9, 0x93, 0x4d, 0x3e, 0x08, + 0xa5, 0x2e, 0x52, 0xd7, 0xda, 0x7d, 0xab, 0xfa, + 0xc4, 0x84, 0xef, 0xe3, 0x7a, 0x53, 0x80, 0xee, + 0x90, 0x88, 0xf7, 0xac, 0xe2, 0xef, 0xcd, 0xe9 + }; - TEST_ASSERT_EQUAL_HEX32(ESP_OK, err); - TEST_ASSERT_NOT_NULL(ptr); + unsigned char psa_output[32]; + unsigned char mbedtls_output[32]; + size_t psa_output_len; + psa_status_t psa_status; + int mbedtls_ret; - /* Compare esp_sha() result to the mbedTLS result, should always be the same */ -#if CONFIG_MBEDTLS_SHA1_C - esp_sha(SHA1, ptr, LEN, sha1_espsha); - r = mbedtls_sha1(ptr, LEN, sha1_mbedtls); - TEST_ASSERT_EQUAL(0, r); -#endif + ESP_LOGI(TAG, "=== Test 1: SHA-256(\"abc\") ==="); - esp_sha(SHA2_256, ptr, LEN, sha256_espsha); - r = mbedtls_sha256(ptr, LEN, sha256_mbedtls, 0); - TEST_ASSERT_EQUAL(0, r); + // Test with PSA + ESP_LOGI(TAG, "Testing PSA psa_hash_compute()..."); + psa_status = psa_hash_compute(PSA_ALG_SHA_256, test1_input, test1_input_len, + psa_output, sizeof(psa_output), &psa_output_len); + ESP_LOGI(TAG, "PSA status: 0x%x, output_len: %zu", (unsigned int)psa_status, psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(32, psa_output_len); -#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C - esp_sha(SHA2_512, ptr, LEN, sha512_espsha); - r = mbedtls_sha512(ptr, LEN, sha512_mbedtls, 0); - TEST_ASSERT_EQUAL(0, r); -#endif + ESP_LOGI(TAG, "PSA result: %02x %02x %02x %02x %02x %02x %02x %02x...", + psa_output[0], psa_output[1], psa_output[2], psa_output[3], + psa_output[4], psa_output[5], psa_output[6], psa_output[7]); + ESP_LOGI(TAG, "Expected result: %02x %02x %02x %02x %02x %02x %02x %02x...", + test1_expected[0], test1_expected[1], test1_expected[2], test1_expected[3], + test1_expected[4], test1_expected[5], test1_expected[6], test1_expected[7]); - /* munmap() 1MB of flash when the usge of memory-mapped ptr is over */ - spi_flash_munmap(handle); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, psa_output, 32); + ESP_LOGI(TAG, "✓ PSA SHA-256(\"abc\") PASSED"); -#if CONFIG_MBEDTLS_SHA1_C - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_espsha, sha1_mbedtls, sizeof(sha1_espsha), "SHA1 results should match"); -#endif + // Test with mbedtls_md + ESP_LOGI(TAG, "Testing mbedtls_md()..."); + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + TEST_ASSERT_NOT_NULL(md_info); - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_espsha, sha256_mbedtls, sizeof(sha256_espsha), "SHA256 results should match"); + mbedtls_ret = mbedtls_md(md_info, test1_input, test1_input_len, mbedtls_output); + ESP_LOGI(TAG, "mbedtls_md return: %d", mbedtls_ret); + TEST_ASSERT_EQUAL(0, mbedtls_ret); -#if SOC_SHA_SUPPORT_SHA512 && CONFIG_MBEDTLS_SHA512_C - TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_espsha, sha512_mbedtls, sizeof(sha512_espsha), "SHA512 results should match"); -#endif + ESP_LOGI(TAG, "mbedtls result: %02x %02x %02x %02x %02x %02x %02x %02x...", + mbedtls_output[0], mbedtls_output[1], mbedtls_output[2], mbedtls_output[3], + mbedtls_output[4], mbedtls_output[5], mbedtls_output[6], mbedtls_output[7]); + + TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, mbedtls_output, 32); + ESP_LOGI(TAG, "✓ mbedtls_md SHA-256(\"abc\") PASSED"); + + // Verify both methods produce the same result + TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 32); + ESP_LOGI(TAG, "✓ PSA and mbedtls_md results match"); + + ESP_LOGI(TAG, "=== Test 2: SHA-256(\"\") (empty string) ==="); + + // Test with PSA + psa_status = psa_hash_compute(PSA_ALG_SHA_256, test2_input, test2_input_len, + psa_output, sizeof(psa_output), &psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(32, psa_output_len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, psa_output, 32); + ESP_LOGI(TAG, "✓ PSA SHA-256(\"\") PASSED"); + + // Test with mbedtls_md + mbedtls_ret = mbedtls_md(md_info, test2_input, test2_input_len, mbedtls_output); + TEST_ASSERT_EQUAL(0, mbedtls_ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, mbedtls_output, 32); + ESP_LOGI(TAG, "✓ mbedtls_md SHA-256(\"\") PASSED"); + + // Verify both methods produce the same result + TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 32); + ESP_LOGI(TAG, "✓ All PSA SHA-256 tests PASSED!"); + + // Test Vector 3: SHA-256("hello world") + // This will do with PSA only but _update will be called multiple time + + ESP_LOGI(TAG, "=== Test 3: SHA-256(\"hello world\") ==="); + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + psa_status = psa_hash_setup(&operation, PSA_ALG_SHA_256); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + psa_status = psa_hash_update(&operation, (const uint8_t *)test3_input, 5); // "hello" + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + psa_status = psa_hash_update(&operation, (const uint8_t *)(test3_input + 5), 6); // " world" + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + psa_status = psa_hash_finish(&operation, psa_output, sizeof(psa_output), &psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(32, psa_output_len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test3_expected, psa_output, 32); + ESP_LOGI(TAG, "✓ PSA SHA-256(\"hello world\") PASSED"); } -#endif - -#if CONFIG_MBEDTLS_HARDWARE_SHA - -TEST_CASE("Test mbedtls_internal_sha_process()", "[hw_crypto]") +TEST_CASE("Test PSA SHA-384 with known test vectors", "[hw_crypto][psa]") { - const size_t BUFFER_SZ = 128; - int ret; - unsigned char output[64] = { 0 }; - void *buffer = heap_caps_malloc(BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - TEST_ASSERT_NOT_NULL(buffer); - memset(buffer, 0xEE, BUFFER_SZ); + ESP_LOGI(TAG, "Testing PSA SHA-384 implementation with known test vectors"); - mbedtls_sha1_context sha1_ctx; + // Test Vector 1: SHA-384("abc") + // Expected: cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7 + const unsigned char test1_input[] = "abc"; + const size_t test1_input_len = 3; + const unsigned char test1_expected[48] = { + 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 + }; - const uint8_t sha1_expected[20] = { 0x41, 0x63, 0x12, 0x5b, 0x9c, 0x68, 0x85, 0xc8, - 0x01, 0x40, 0xf4, 0x03, 0x5d, 0x0d, 0x84, 0x0e, - 0xa4, 0xae, 0x4d, 0xe9 }; + // Test Vector 2: SHA-384("") + // Expected: 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b + const unsigned char test2_input[] = ""; + const size_t test2_input_len = 0; + const unsigned char test2_expected[48] = { + 0x38, 0xb0, 0x60, 0xa7, 0x51, 0xac, 0x96, 0x38, + 0x4c, 0xd9, 0x32, 0x7e, 0xb1, 0xb1, 0xe3, 0x6a, + 0x21, 0xfd, 0xb7, 0x11, 0x14, 0xbe, 0x07, 0x43, + 0x4c, 0x0c, 0xc7, 0xbf, 0x63, 0xf6, 0xe1, 0xda, + 0x27, 0x4e, 0xde, 0xbf, 0xe7, 0x6f, 0x65, 0xfb, + 0xd5, 0x1a, 0xd2, 0xf1, 0x48, 0x98, 0xb9, 0x5b + }; - mbedtls_sha1_init(&sha1_ctx); - mbedtls_sha1_starts(&sha1_ctx); + // Test Vector 3: SHA-384("hello world") + // Expected: fdbd8e75a67f29f701a4e040385e2e23986303ea10239211af907fcbb83578b3e417cb71ce646efd0819dd8c088de1bd + const unsigned char test3_input[] = "hello world"; + const unsigned char test3_expected[48] = { + 0xfd, 0xbd, 0x8e, 0x75, 0xa6, 0x7f, 0x29, 0xf7, + 0x01, 0xa4, 0xe0, 0x40, 0x38, 0x5e, 0x2e, 0x23, + 0x98, 0x63, 0x03, 0xea, 0x10, 0x23, 0x92, 0x11, + 0xaf, 0x90, 0x7f, 0xcb, 0xb8, 0x35, 0x78, 0xb3, + 0xe4, 0x17, 0xcb, 0x71, 0xce, 0x64, 0x6e, 0xfd, + 0x08, 0x19, 0xdd, 0x8c, 0x08, 0x8d, 0xe1, 0xbd + }; - ret = mbedtls_internal_sha1_process(&sha1_ctx, buffer); - TEST_ASSERT_EQUAL(0, ret); + unsigned char psa_output[48]; + unsigned char mbedtls_output[48]; + size_t psa_output_len; + psa_status_t psa_status; + int mbedtls_ret; - ret = mbedtls_internal_sha1_process(&sha1_ctx, buffer); - TEST_ASSERT_EQUAL(0, ret); + ESP_LOGI(TAG, "=== Test 1: SHA-384(\"abc\") ==="); -#if SOC_SHA_ENDIANNESS_BE - for (int i = 0; i < sizeof(sha1_ctx.state)/sizeof(sha1_ctx.state[0]); i++) - { - *(uint32_t *)(output + i*4) = __builtin_bswap32(sha1_ctx.state[i]); - } -#else - memcpy(output, sha1_ctx.state, 20); -#endif + // Test with PSA + ESP_LOGI(TAG, "Testing PSA psa_hash_compute()..."); + psa_status = psa_hash_compute(PSA_ALG_SHA_384, test1_input, test1_input_len, + psa_output, sizeof(psa_output), &psa_output_len); + ESP_LOGI(TAG, "PSA status: 0x%x, output_len: %zu", (unsigned int)psa_status, psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(48, psa_output_len); - // Check if the intermediate states are correct - TEST_ASSERT_EQUAL_HEX8_ARRAY(sha1_expected, output, sizeof(sha1_expected)); + ESP_LOGI(TAG, "PSA result: %02x %02x %02x %02x %02x %02x %02x %02x...", + psa_output[0], psa_output[1], psa_output[2], psa_output[3], + psa_output[4], psa_output[5], psa_output[6], psa_output[7]); + ESP_LOGI(TAG, "Expected result: %02x %02x %02x %02x %02x %02x %02x %02x...", + test1_expected[0], test1_expected[1], test1_expected[2], test1_expected[3], + test1_expected[4], test1_expected[5], test1_expected[6], test1_expected[7]); - ret = mbedtls_sha1_finish(&sha1_ctx, output); - TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, psa_output, 48); + ESP_LOGI(TAG, "✓ PSA SHA-384(\"abc\") PASSED"); - mbedtls_sha1_free(&sha1_ctx); + // Test with mbedtls_md + ESP_LOGI(TAG, "Testing mbedtls_md()..."); + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); + TEST_ASSERT_NOT_NULL(md_info); -#if SOC_SHA_SUPPORT_SHA512 - mbedtls_sha512_context sha512_ctx; + mbedtls_ret = mbedtls_md(md_info, test1_input, test1_input_len, mbedtls_output); + ESP_LOGI(TAG, "mbedtls_md return: %d", mbedtls_ret); + TEST_ASSERT_EQUAL(0, mbedtls_ret); - const uint8_t sha512_expected[64] = { 0x3c, 0x77, 0x5f, 0xb0, 0x3b, 0x25, 0x8d, 0x3b, - 0xa9, 0x28, 0xa2, 0x29, 0xf2, 0x14, 0x7d, 0xb3, - 0x64, 0x1e, 0x76, 0xd5, 0x0b, 0xbc, 0xdf, 0xb4, - 0x75, 0x1d, 0xe7, 0x7f, 0x62, 0x83, 0xdd, 0x78, - 0x6b, 0x0e, 0xa4, 0xd2, 0xbe, 0x51, 0x56, 0xd4, - 0xfe, 0x3b, 0xa3, 0x3a, 0xd7, 0xf6, 0xd3, 0xb3, - 0xe7, 0x9d, 0xb5, 0xe6, 0x76, 0x35, 0x2a, 0xae, - 0x07, 0x0a, 0x3a, 0x03, 0x44, 0xf0, 0xb8, 0xfe }; + ESP_LOGI(TAG, "mbedtls result: %02x %02x %02x %02x %02x %02x %02x %02x...", + mbedtls_output[0], mbedtls_output[1], mbedtls_output[2], mbedtls_output[3], + mbedtls_output[4], mbedtls_output[5], mbedtls_output[6], mbedtls_output[7]); - mbedtls_sha512_init(&sha512_ctx); - mbedtls_sha512_starts(&sha512_ctx, 0); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test1_expected, mbedtls_output, 48); + ESP_LOGI(TAG, "✓ mbedtls_md SHA-384(\"abc\") PASSED"); - ret = mbedtls_internal_sha512_process(&sha512_ctx, buffer); - TEST_ASSERT_EQUAL(0, ret); + // Verify both methods produce the same result + TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 48); + ESP_LOGI(TAG, "✓ PSA and mbedtls_md results match"); - ret = mbedtls_internal_sha512_process(&sha512_ctx, buffer); - TEST_ASSERT_EQUAL(0, ret); + ESP_LOGI(TAG, "=== Test 2: SHA-384(\"\") (empty string) ==="); -#if SOC_SHA_ENDIANNESS_BE - for (int i = 0; i < sizeof(sha512_ctx.state)/sizeof(sha512_ctx.state[0]); i++) - { - *(uint64_t *)(output + i*8) = __builtin_bswap64(sha512_ctx.state[i]); - } -#else - memcpy(output, sha512_ctx.state, 64); -#endif + // Test with PSA + psa_status = psa_hash_compute(PSA_ALG_SHA_384, test2_input, test2_input_len, + psa_output, sizeof(psa_output), &psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(48, psa_output_len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, psa_output, 48); + ESP_LOGI(TAG, "✓ PSA SHA-384(\"\") PASSED"); - // Check if the intermediate states are correct - TEST_ASSERT_EQUAL_HEX8_ARRAY(sha512_expected, output, sizeof(sha512_expected)); + // Test with mbedtls_md + mbedtls_ret = mbedtls_md(md_info, test2_input, test2_input_len, mbedtls_output); + TEST_ASSERT_EQUAL(0, mbedtls_ret); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test2_expected, mbedtls_output, 48); + ESP_LOGI(TAG, "✓ mbedtls_md SHA-384(\"\") PASSED"); - ret = mbedtls_sha512_finish(&sha512_ctx, output); - TEST_ASSERT_EQUAL(0, ret); + // Verify both methods produce the same result + TEST_ASSERT_EQUAL_MEMORY(psa_output, mbedtls_output, 48); + ESP_LOGI(TAG, "✓ All PSA SHA-384 tests PASSED!"); - mbedtls_sha512_free(&sha512_ctx); - -#endif - free(buffer); + // Test Vector 3: SHA-384("hello world") + // This will do with PSA only but _update will be called multiple time + ESP_LOGI(TAG, "=== Test 3: SHA-384(\"hello world\") ==="); + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + psa_status = psa_hash_setup(&operation, PSA_ALG_SHA_384); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + psa_status = psa_hash_update(&operation, (const uint8_t *)test3_input, 5); // "hello" + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + psa_status = psa_hash_update(&operation, (const uint8_t *)(test3_input + 5), 6); // " world" + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + psa_status = psa_hash_finish(&operation, psa_output, sizeof(psa_output), &psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(48, psa_output_len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test3_expected, psa_output, 48); + ESP_LOGI(TAG, "✓ PSA SHA-384(\"hello world\") PASSED"); } -#endif -#endif // SOC_SHA_SUPPORTED +TEST_CASE("Test PSA SHA-384 with clone", "[hw_crypto][psa]") +{ + // Test Vector 1: SHA-384("hello world") + // Expected: fdbd8e75a67f29f701a4e040385e2e23986303ea10239211af907fcbb83578b3e417cb71ce646efd0819dd8c088de1bd + const unsigned char test3_input[] = "hello world"; + const unsigned char test3_expected[48] = { + 0xfd, 0xbd, 0x8e, 0x75, 0xa6, 0x7f, 0x29, 0xf7, + 0x01, 0xa4, 0xe0, 0x40, 0x38, 0x5e, 0x2e, 0x23, + 0x98, 0x63, 0x03, 0xea, 0x10, 0x23, 0x92, 0x11, + 0xaf, 0x90, 0x7f, 0xcb, 0xb8, 0x35, 0x78, 0xb3, + 0xe4, 0x17, 0xcb, 0x71, 0xce, 0x64, 0x6e, 0xfd, + 0x08, 0x19, 0xdd, 0x8c, 0x08, 0x8d, 0xe1, 0xbd + }; + + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + psa_status_t psa_status = psa_hash_setup(&operation, PSA_ALG_SHA_384); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + psa_status = psa_hash_update(&operation, (const uint8_t *)test3_input, 5); // "hello" + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + + psa_hash_operation_t clone = PSA_HASH_OPERATION_INIT; + psa_status = psa_hash_clone(&operation, &clone); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + psa_status = psa_hash_update(&clone, (const uint8_t *)(test3_input + 5), 6); // " world" + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + unsigned char psa_output[48]; + size_t psa_output_len; + psa_status = psa_hash_finish(&clone, psa_output, sizeof(psa_output), &psa_output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_status); + TEST_ASSERT_EQUAL(48, psa_output_len); + TEST_ASSERT_EQUAL_HEX8_ARRAY(test3_expected, psa_output, 48); + ESP_LOGI(TAG, "✓ PSA SHA-384(\"hello world\") with original PASSED"); +} diff --git a/components/mbedtls/test_apps/main/test_sha_perf.c b/components/mbedtls/test_apps/main/test_sha_perf.c index c53371dd713..53ba6078728 100644 --- a/components/mbedtls/test_apps/main/test_sha_perf.c +++ b/components/mbedtls/test_apps/main/test_sha_perf.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,38 +10,44 @@ #include #include #include -#include "mbedtls/sha256.h" #include "unity.h" #include "sdkconfig.h" #include "esp_heap_caps.h" #include "test_utils.h" #include "ccomp_timer.h" #include "test_mbedtls_utils.h" +#include "psa/crypto.h" -TEST_CASE("mbedtls SHA performance", "[mbedtls]") +#include "psa/crypto.h" + +TEST_CASE("psa SHA256 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 diff --git a/components/mbedtls/test_apps/pytest_mbedtls_ut.py b/components/mbedtls/test_apps/pytest_mbedtls_ut.py index 1265f189957..2edea13c176 100644 --- a/components/mbedtls/test_apps/pytest_mbedtls_ut.py +++ b/components/mbedtls/test_apps/pytest_mbedtls_ut.py @@ -91,17 +91,18 @@ def test_mbedtls_ecdsa_sign(dut: Dut) -> None: dut.run_all_single_board_cases(group='efuse_key') -@pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - 'rom_impl', - ], - indirect=True, -) -@idf_parametrize('target', ['esp32c2'], indirect=['target']) -def test_mbedtls_rom_impl_esp32c2(dut: Dut) -> None: - dut.run_all_single_board_cases() +# TODO: IDF-15012 +# @pytest.mark.generic +# @pytest.mark.parametrize( +# 'config', +# [ +# 'rom_impl', +# ], +# indirect=True, +# ) +# @idf_parametrize('target', ['esp32c2'], indirect=['target']) +# def test_mbedtls_rom_impl_esp32c2(dut: Dut) -> None: +# dut.run_all_single_board_cases() @pytest.mark.generic diff --git a/components/mbedtls/test_apps/sdkconfig.ci.rom_impl b/components/mbedtls/test_apps/sdkconfig.ci.rom_impl index 4f79484e475..53574d1c42d 100644 --- a/components/mbedtls/test_apps/sdkconfig.ci.rom_impl +++ b/components/mbedtls/test_apps/sdkconfig.ci.rom_impl @@ -1,2 +1,3 @@ CONFIG_IDF_TARGET="esp32c2" -CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=y +# TODO: IDF-15012 +# CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=y diff --git a/components/nvs_flash/src/nvs_bootloader_aes.c b/components/nvs_flash/src/nvs_bootloader_aes.c index 5cbbab5ad03..bd39b7d965c 100644 --- a/components/nvs_flash/src/nvs_bootloader_aes.c +++ b/components/nvs_flash/src/nvs_bootloader_aes.c @@ -70,7 +70,9 @@ int nvs_bootloader_aes_crypt_ecb(enum AES_TYPE mode, } #endif /* CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB */ #else /* BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER */ -#include "mbedtls/aes.h" +#include "psa/crypto.h" + +static const char *TAG = "nvs_bootloader_aes"; int nvs_bootloader_aes_crypt_ecb(enum AES_TYPE mode, const unsigned char *key, @@ -78,34 +80,66 @@ int nvs_bootloader_aes_crypt_ecb(enum AES_TYPE mode, const unsigned char input[16], unsigned char output[16]) { - int ret = -1; - + psa_status_t status; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); uint16_t keybits = key_bits == AES256 ? 256 : key_bits == AES192 ? 192 : 128; - int mbedtls_aes_mode = mode == AES_ENC ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT; - - mbedtls_aes_context ctx; - mbedtls_aes_init(&ctx); + psa_set_key_bits(&key_attributes, keybits); + status = psa_import_key(&key_attributes, key, keybits / 8, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to import key: %d", status); + return -1; + } + psa_reset_key_attributes(&key_attributes); if (mode == AES_ENC) { - ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_ECB_NO_PADDING); } else { - ret = mbedtls_aes_setkey_dec(&ctx, key, keybits); + status = psa_cipher_decrypt_setup(&operation, key_id, PSA_ALG_ECB_NO_PADDING); + } + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to setup cipher operation: %d", status); + psa_destroy_key(key_id); + return -1; } - if (ret != 0) { - mbedtls_aes_free(&ctx); - return ret; + size_t output_len = 0; + status = psa_cipher_update(&operation, input, 16, output, 16, &output_len); + if (status != PSA_SUCCESS || output_len != 16) { + ESP_LOGE(TAG, "Failed to update cipher operation: %d", status); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; } - ret = mbedtls_aes_crypt_ecb(&ctx, mbedtls_aes_mode, input, output); - - if (ret != 0) { - mbedtls_aes_free(&ctx); - return ret; + status = psa_cipher_finish(&operation, output + output_len, 16 - output_len, &output_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to finish cipher operation: %d", status); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; } - mbedtls_aes_free(&ctx); - return ret; + if (output_len != 0) { + ESP_LOGE(TAG, "Output length mismatch: expected 0, got %zu", output_len); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + status = psa_cipher_finish(&operation, output, 16, &output_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to finish cipher operation: %d", status); + psa_destroy_key(key_id); + return -1; + } + + psa_destroy_key(key_id); + return 0; } #endif /* !(BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER) */ #endif /* !SOC_AES_SUPPORTED */ diff --git a/components/nvs_flash/src/nvs_bootloader_xts_aes.c b/components/nvs_flash/src/nvs_bootloader_xts_aes.c index ce204f6a9d2..331483e6e14 100644 --- a/components/nvs_flash/src/nvs_bootloader_xts_aes.c +++ b/components/nvs_flash/src/nvs_bootloader_xts_aes.c @@ -257,7 +257,8 @@ int nvs_bootloader_aes_crypt_xts(nvs_bootloader_xts_aes_context *ctx, #endif /* CONFIG_ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB */ #else /* BOOTLOADER_BUILD && !CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL_BOOTLOADER */ -#include "mbedtls/aes.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include "mbedtls/private/aes.h" static mbedtls_aes_xts_context ctx_xts; @@ -291,7 +292,6 @@ int nvs_bootloader_aes_crypt_xts(nvs_bootloader_xts_aes_context *ctx, unsigned char *output) { (void) ctx; - int mbedtls_aes_mode = mode == AES_ENC ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT; return mbedtls_aes_crypt_xts(&ctx_xts, mbedtls_aes_mode, length, data_unit, input, output); } diff --git a/components/nvs_flash/src/nvs_encrypted_partition.hpp b/components/nvs_flash/src/nvs_encrypted_partition.hpp index 6cf128203d5..d1060999ef4 100644 --- a/components/nvs_flash/src/nvs_encrypted_partition.hpp +++ b/components/nvs_flash/src/nvs_encrypted_partition.hpp @@ -6,8 +6,14 @@ #pragma once #include "sdkconfig.h" // For CONFIG_NVS_BDL_STACK -#include "mbedtls/aes.h" // For mbedtls_aes_xts_context -#include "nvs_flash.h" // For nvs_sec_cfg_t + +/* NOTE: Using legacy mbedtls XTS API until PSA Crypto adds XTS support +* With TF-PSA-Crypto 1.0, AES headers moved to mbedtls/private/. +* Need MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS to access XTS functions. +*/ +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include "mbedtls/private/aes.h" +#include "nvs_flash.h" #include "nvs_partition.hpp" namespace nvs { diff --git a/components/nvs_flash/test_apps/main/app_main.c b/components/nvs_flash/test_apps/main/app_main.c index 17601f77a18..9707d52cfb7 100644 --- a/components/nvs_flash/test_apps/main/app_main.c +++ b/components/nvs_flash/test_apps/main/app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -8,7 +8,7 @@ #include "unity.h" #include "esp_partition.h" #ifdef CONFIG_NVS_ENCRYPTION -#include "mbedtls/aes.h" +// #include "mbedtls/aes.h" #endif #include "memory_checks.h" #include "esp_newlib.h" @@ -60,13 +60,6 @@ int32_t get_heap_free_difference(const bool nvs_active_pool) /* setUp runs before every test */ void setUp(void) { - // Execute mbedtls_aes_init operation to allocate AES interrupt - // allocation memory which is considered as memory leak otherwise -#if defined(CONFIG_NVS_ENCRYPTION) && defined(SOC_AES_SUPPORTED) - mbedtls_aes_context ctx; - mbedtls_aes_init(&ctx); -#endif - // Calling esp_partition_find_first ensures that the partitions have been loaded // and subsequent calls to esp_partition_find_first from the tests would not // load partitions which otherwise gets considered as a memory leak. diff --git a/components/nvs_flash/test_apps/main/test_nvs.c b/components/nvs_flash/test_apps/main/test_nvs.c index 04e4efc061a..e4d1dfc5ca4 100644 --- a/components/nvs_flash/test_apps/main/test_nvs.c +++ b/components/nvs_flash/test_apps/main/test_nvs.c @@ -29,7 +29,8 @@ #include "esp_random.h" #ifdef CONFIG_NVS_ENCRYPTION -#include "mbedtls/aes.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS +#include "mbedtls/private/aes.h" #endif #ifdef CONFIG_SOC_HMAC_SUPPORTED diff --git a/components/openthread/CMakeLists.txt b/components/openthread/CMakeLists.txt index d9322f3a330..225be6b63eb 100644 --- a/components/openthread/CMakeLists.txt +++ b/components/openthread/CMakeLists.txt @@ -43,7 +43,11 @@ if(CONFIG_OPENTHREAD_ENABLED) set(exclude_srcs "openthread/examples/platforms/utils/logging_rtt.c" "openthread/examples/platforms/utils/soft_source_match_table.c" - "openthread/src/core/instance/extension_example.cpp") + "openthread/src/core/instance/extension_example.cpp" + "openthread/src/core/crypto/crypto_platform_mbedtls.cpp" + "openthread/src/core/api/random_crypto_api.cpp" + ) + if(CONFIG_OPENTHREAD_FTD OR CONFIG_OPENTHREAD_MTD) list(APPEND src_dirs diff --git a/components/openthread/openthread b/components/openthread/openthread index 36b14d3ef74..7d4fa4223fb 160000 --- a/components/openthread/openthread +++ b/components/openthread/openthread @@ -1 +1 @@ -Subproject commit 36b14d3ef74f5e37e5be8902e1c1955a642fdfbf +Subproject commit 7d4fa4223fbb19e610f054aabcf3ce87ae074ffe diff --git a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h index 284c5493fe1..0f776479ceb 100644 --- a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h @@ -891,3 +891,7 @@ #ifndef OPENTHREAD_CONFIG_THREAD_VERSION #define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_4 #endif + +#define OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE 1 + +#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA diff --git a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h index 045faff3237..c278420b7fb 100644 --- a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h @@ -493,3 +493,7 @@ #ifndef OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD #define OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD CONFIG_OPENTHREAD_PARENT_SEARCH_RSS_THRESHOLD #endif + +#define OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE 1 + +#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA diff --git a/components/openthread/private_include/openthread-core-esp32x-radio-config.h b/components/openthread/private_include/openthread-core-esp32x-radio-config.h index 3df6677e2e1..215d82f9203 100644 --- a/components/openthread/private_include/openthread-core-esp32x-radio-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-radio-config.h @@ -279,3 +279,6 @@ #ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE #define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE 1 #endif + +#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA +#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 0 diff --git a/components/openthread/sbom_openthread.yml b/components/openthread/sbom_openthread.yml index 74398658c69..00a39997b16 100644 --- a/components/openthread/sbom_openthread.yml +++ b/components/openthread/sbom_openthread.yml @@ -5,4 +5,4 @@ supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' originator: 'Organization: Google LLC' description: OpenThread released by Google is an open-source implementation of the Thread networking url: https://github.com/espressif/openthread -hash: 36b14d3ef74f5e37e5be8902e1c1955a642fdfbf +hash: 7d4fa4223fbb19e610f054aabcf3ce87ae074ffe diff --git a/components/openthread/src/port/esp_openthread_radio.c b/components/openthread/src/port/esp_openthread_radio.c index c5d32fa09f0..83e5c7aa64a 100644 --- a/components/openthread/src/port/esp_openthread_radio.c +++ b/components/openthread/src/port/esp_openthread_radio.c @@ -31,6 +31,7 @@ #include "openthread/platform/time.h" #include "utils/link_metrics.h" #include "utils/mac_frame.h" +#include "psa/crypto.h" #if (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE) #include "esp_coex_i154.h" @@ -88,6 +89,17 @@ static uint32_t s_ack_frame_counter; static uint8_t s_ack_key_id; static uint8_t s_security_key[16]; static uint8_t s_security_addr[8]; + +static void ot_set_security_key_from_key_material(struct otMacKeyMaterial a_key_material) +{ +#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE + size_t keyLength = 0; + psa_export_key(a_key_material.mKeyMaterial.mKeyRef, s_security_key, 16, &keyLength); +#else + memcpy(s_security_key, a_key_material.mKeyMaterial.mKey.m8, sizeof(a_key_material.mKeyMaterial.mKey.m8)); +#endif +} + #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 static esp_openthread_circular_queue_info_t s_recv_queue = {.head = 0, .tail = 0, .used = 0}; @@ -305,7 +317,7 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) } esp_ieee802154_get_extended_address(s_security_addr); } - memcpy(s_security_key, s_current_key.mKeyMaterial.mKey.m8, sizeof(s_current_key.mKeyMaterial.mKey.m8)); + ot_set_security_key_from_key_material(s_current_key); esp_ieee802154_set_transmit_security(&aFrame->mPsdu[-1], s_security_key, s_security_addr); } @@ -488,7 +500,11 @@ void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKe { OT_UNUSED_VARIABLE(aInstance); OT_UNUSED_VARIABLE(aKeyIdMode); +#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE + assert(aKeyType == OT_KEY_TYPE_KEY_REF); +#else assert(aKeyType == OT_KEY_TYPE_LITERAL_KEY); +#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE assert(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL); s_key_id = aKeyId; @@ -630,7 +646,7 @@ static esp_err_t IRAM_ATTR enh_ack_set_security_addr_and_key(otRadioFrame *ack_f s_with_security_enh_ack = true; if (otMacFrameIsKeyIdMode1(ack_frame)) { esp_ieee802154_get_extended_address(s_security_addr); - memcpy(s_security_key, (*key).mKeyMaterial.mKey.m8, OT_MAC_KEY_SIZE); + ot_set_security_key_from_key_material(*key); } esp_ieee802154_set_transmit_security(&ack_frame->mPsdu[-1], s_security_key, s_security_addr); diff --git a/components/protocomm/src/crypto/srp6a/esp_srp.c b/components/protocomm/src/crypto/srp6a/esp_srp.c index bf3dd25cc5b..1ae4aa80022 100644 --- a/components/protocomm/src/crypto/srp6a/esp_srp.c +++ b/components/protocomm/src/crypto/srp6a/esp_srp.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,9 +9,10 @@ #include "esp_log.h" #include "esp_err.h" -#include +#include "psa/crypto.h" #include "esp_srp_mpi.h" #include "esp_srp.h" +#include "esp_check.h" #define SHA512_HASH_SZ 64 @@ -178,33 +179,63 @@ void esp_srp_free(esp_srp_handle_t *hd) static esp_mpi_t *calculate_x(char *bytes_salt, int salt_len, const char *username, int username_len, const char *pass, int pass_len) { - unsigned char digest[SHA512_HASH_SZ]; - mbedtls_sha512_context ctx; - ESP_LOGD(TAG, "Username: %s | Passphrase: %s | Passphrase length: %d", username, pass, pass_len); - mbedtls_sha512_init(&ctx); - mbedtls_sha512_starts(&ctx, 0); - mbedtls_sha512_update(&ctx, (unsigned char *)username, username_len); - mbedtls_sha512_update(&ctx, (unsigned char *)":", 1); - mbedtls_sha512_update(&ctx, (unsigned char *)pass, pass_len); - mbedtls_sha512_finish(&ctx, digest); + // ret is unused here as it is required by the esp_check macros, suppressing the unused variable warning + __attribute__((unused)) esp_err_t ret = ESP_FAIL; - mbedtls_sha512_init(&ctx); - mbedtls_sha512_starts(&ctx, 0); - mbedtls_sha512_update(&ctx, (unsigned char *)bytes_salt, salt_len); - mbedtls_sha512_update(&ctx, digest, sizeof(digest)); - mbedtls_sha512_finish(&ctx, digest); - mbedtls_sha512_free(&ctx); + unsigned char digest[SHA512_HASH_SZ]; + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status; + + /* Add validation for input parameters */ + if (!bytes_salt || !username || !pass || salt_len <= 0 || username_len <= 0 || pass_len <= 0) { + ESP_LOGE(TAG, "Invalid parameters: salt=%p, username=%p, pass=%p, salt_len=%d, username_len=%d, pass_len=%d", + bytes_salt, username, pass, salt_len, username_len, pass_len); + return NULL; + } + + ESP_LOGD(TAG, "Username: %s | Passphrase: %s | Passphrase length: %d", username, pass, pass_len); + + status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + ESP_RETURN_ON_FALSE(status == PSA_SUCCESS, NULL, TAG, "Failed to setup hash operation: %d", status); + psa_hash_update(&hash_op, (unsigned char *)username, username_len); + psa_hash_update(&hash_op, (unsigned char *)":", 1); + psa_hash_update(&hash_op, (unsigned char *)pass, pass_len); + + size_t hash_len = 0; + status = psa_hash_finish(&hash_op, digest, sizeof(digest), &hash_len); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS && hash_len == SHA512_HASH_SZ, ESP_FAIL, error, TAG, + "Hash operation failed: status=%d, hash_len=%d", status, hash_len); + status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + ESP_RETURN_ON_FALSE(status == PSA_SUCCESS, NULL, TAG, "Failed to setup hash operation: %d", status); + + psa_hash_update(&hash_op, (unsigned char *)bytes_salt, salt_len); + psa_hash_update(&hash_op, digest, sizeof(digest)); + status = psa_hash_finish(&hash_op, digest, sizeof(digest), &hash_len); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS && hash_len == SHA512_HASH_SZ, ESP_FAIL, error, TAG, + "Hash operation failed: status=%d, hash_len=%d", status, hash_len); return esp_mpi_new_from_bin((char *)digest, sizeof(digest)); +error: + psa_hash_abort(&hash_op); + return NULL; } static esp_mpi_t *calculate_padded_hash(esp_srp_handle_t *hd, const char *a, int len_a, const char *b, int len_b) { unsigned char digest[SHA512_HASH_SZ]; - mbedtls_sha512_context ctx; + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status; int pad_len; + size_t hash_len = 0; char *s = NULL; + /* Add validation for input parameters */ + if (!hd || !a || !b || len_a <= 0 || len_b <= 0) { + ESP_LOGE(TAG, "Invalid parameters: hd=%p, a=%p, b=%p, len_a=%d, len_b=%d", + hd, a, b, len_a, len_b); + return NULL; + } + if (len_a > len_b) { pad_len = hd->len_n - len_b; } else { @@ -218,28 +249,37 @@ static esp_mpi_t *calculate_padded_hash(esp_srp_handle_t *hd, const char *a, int } } - mbedtls_sha512_init(&ctx); - mbedtls_sha512_starts(&ctx, 0); - /* PAD (a) */ - if (s && (len_a != hd->len_n)) { - mbedtls_sha512_update(&ctx, (unsigned char *)s, hd->len_n - len_a); + status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to setup hash operation: %d", status); + if (s) { + free(s); + } + return NULL; } - mbedtls_sha512_update(&ctx, (unsigned char *)a, len_a); + /* PAD (a) */ + if (s && (len_a != hd->len_n)) { + psa_hash_update(&hash_op, (unsigned char *)s, hd->len_n - len_a); + } + + psa_hash_update(&hash_op, (unsigned char *)a, len_a); /* PAD (b) */ if (s && (len_b != hd->len_n)) { - mbedtls_sha512_update(&ctx, (unsigned char *)s, hd->len_n - len_b); + psa_hash_update(&hash_op, (unsigned char *)s, hd->len_n - len_b); } - mbedtls_sha512_update(&ctx, (unsigned char *)b, len_b); - - mbedtls_sha512_finish(&ctx, digest); - mbedtls_sha512_free(&ctx); - + psa_hash_update(&hash_op, (unsigned char *)b, len_b); + status = psa_hash_finish(&hash_op, digest, sizeof(digest), &hash_len); if (s) { free(s); } + if (status != PSA_SUCCESS || hash_len != SHA512_HASH_SZ) { + psa_hash_abort(&hash_op); + ESP_LOGE(TAG, "Hash operation failed: status=%d, hash_len=%d", status, hash_len); + return NULL; + } return esp_mpi_new_from_bin((char *)digest, sizeof(digest)); } @@ -250,24 +290,53 @@ static esp_mpi_t *calculate_padded_hash(esp_srp_handle_t *hd, const char *a, int */ static esp_mpi_t *calculate_k(esp_srp_handle_t *hd) { + if (!hd) { + ESP_LOGE(TAG, "Invalid parameter: hd=%p", hd); + return NULL; + } return calculate_padded_hash(hd, hd->bytes_n, hd->len_n, hd->bytes_g, hd->len_g); } static esp_mpi_t *calculate_u(esp_srp_handle_t *hd, char *A, int len_A) { + if (!hd || !A || len_A <= 0) { + ESP_LOGE(TAG, "Invalid parameters: hd=%p, A=%p, len_A=%d", hd, A, len_A); + return NULL; + } return calculate_padded_hash(hd, A, len_A, hd->bytes_B, hd->len_B); } static esp_err_t __esp_srp_srv_pubkey(esp_srp_handle_t *hd, char **bytes_B, int *len_B) { - esp_mpi_t *k = calculate_k(hd); + esp_mpi_t *k = NULL; esp_mpi_t *kv = NULL; esp_mpi_t *gb = NULL; + + /* Add validation for input parameters */ + if (!hd || !bytes_B || !len_B) { + ESP_LOGE(TAG, "Invalid parameters: hd=%p, bytes_B=%p, len_B=%p", hd, bytes_B, len_B); + return ESP_ERR_INVALID_ARG; + } + + if (!hd->v) { + ESP_LOGE(TAG, "Verifier must be set before generating server public key"); + return ESP_ERR_INVALID_STATE; + } + + k = calculate_k(hd); if (!k) { goto error; } hexdump_mpi("k", k); + // At this point hd->b, hd->B must be NULL + // If it is not NULL, then free it. + if (hd->b || hd->B) { + esp_mpi_free(hd->b); + hd->b = NULL; + esp_mpi_free(hd->B); + hd->B = NULL; + } hd->b = esp_mpi_new(); if (!hd->b) { goto error; @@ -317,6 +386,18 @@ error: static esp_err_t _esp_srp_gen_salt_verifier(esp_srp_handle_t *hd, const char *username, int username_len, const char *pass, int pass_len, int salt_len) { + /* Add validation for input parameters */ + if (!hd || !username || !pass) { + ESP_LOGE(TAG, "Invalid parameters: hd=%p, username=%p, pass=%p", hd, username, pass); + return ESP_ERR_INVALID_ARG; + } + + if (username_len <= 0 || pass_len <= 0 || salt_len <= 0) { + ESP_LOGE(TAG, "Invalid length parameters: username_len=%d, pass_len=%d, salt_len=%d", + username_len, pass_len, salt_len); + return ESP_ERR_INVALID_ARG; + } + /* Get Salt */ int str_salt_len; esp_mpi_t *x = NULL; @@ -382,9 +463,16 @@ esp_err_t esp_srp_srv_pubkey(esp_srp_handle_t *hd, const char *username, int use const char *pass, int pass_len, int salt_len, char **bytes_B, int *len_B, char **bytes_salt) { - if (!hd || !username || !pass) { + if (!hd || !username || !pass || !bytes_B || !len_B || !bytes_salt) { return ESP_ERR_INVALID_ARG; } + + if (username_len <= 0 || pass_len <= 0 || salt_len <= 0) { + ESP_LOGE(TAG, "Invalid length parameters: username_len=%d, pass_len=%d, salt_len=%d", + username_len, pass_len, salt_len); + return ESP_ERR_INVALID_ARG; + } + if (ESP_OK != _esp_srp_gen_salt_verifier(hd, username, username_len, pass, pass_len, salt_len)) { goto error; } @@ -429,6 +517,19 @@ esp_err_t esp_srp_gen_salt_verifier(const char *username, int username_len, { esp_err_t ret = ESP_FAIL; + /* Add validation for input parameters */ + if (!username || !pass || !bytes_salt || !verifier || !verifier_len) { + ESP_LOGE(TAG, "Invalid parameters: username=%p, pass=%p, bytes_salt=%p, verifier=%p, verifier_len=%p", + username, pass, bytes_salt, verifier, verifier_len); + return ESP_ERR_INVALID_ARG; + } + + if (username_len <= 0 || pass_len <= 0 || salt_len <= 0) { + ESP_LOGE(TAG, "Invalid length parameters: username_len=%d, pass_len=%d, salt_len=%d", + username_len, pass_len, salt_len); + return ESP_ERR_INVALID_ARG; + } + /* allocate and init temporary SRP handle */ esp_srp_handle_t *srp_hd = esp_srp_init(ESP_NG_3072); if (!srp_hd) { @@ -461,6 +562,16 @@ cleanup: esp_err_t esp_srp_set_salt_verifier(esp_srp_handle_t *hd, const char *salt, int salt_len, const char *verifier, int verifier_len) { + if (!hd || !salt || !verifier) { + return ESP_ERR_INVALID_ARG; + } + + if (salt_len <= 0 || verifier_len <= 0) { + ESP_LOGE(TAG, "Invalid length parameters: salt_len=%d, verifier_len=%d", + salt_len, verifier_len); + return ESP_ERR_INVALID_ARG; + } + hd->bytes_s = malloc(salt_len); if (!hd->bytes_s) { goto error; @@ -498,6 +609,26 @@ error: esp_err_t esp_srp_get_session_key(esp_srp_handle_t *hd, char *bytes_A, int len_A, char **bytes_key, uint16_t *len_key) { + esp_err_t ret = ESP_FAIL; + + /* Add validation for input parameters */ + if (!hd || !bytes_A || !bytes_key || !len_key) { + ESP_LOGE(TAG, "Invalid parameters: hd=%p, bytes_A=%p, bytes_key=%p, len_key=%p", + hd, bytes_A, bytes_key, len_key); + return ESP_ERR_INVALID_ARG; + } + + if (len_A <= 0) { + ESP_LOGE(TAG, "Invalid length parameter: len_A=%d", len_A); + return ESP_ERR_INVALID_ARG; + } + + /* Check if the necessary SRP parameters are initialized */ + if (!hd->b || !hd->v || !hd->n) { + ESP_LOGE(TAG, "SRP parameters not properly initialized"); + return ESP_ERR_INVALID_STATE; + } + esp_mpi_t *u = NULL; esp_mpi_t *vu = NULL; esp_mpi_t *avu = NULL; @@ -545,9 +676,16 @@ esp_err_t esp_srp_get_session_key(esp_srp_handle_t *hd, char *bytes_A, int len_A goto error; } - mbedtls_sha512((unsigned char *)bytes_S, len_S, (unsigned char *)hd->session_key, 0); + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS, ESP_FAIL, error, TAG, "Failed to setup hash operation: %d", status); + psa_hash_update(&hash_op, (unsigned char *)bytes_S, len_S); + size_t hash_len = 0; + status = psa_hash_finish(&hash_op, (unsigned char *)hd->session_key, SHA512_HASH_SZ, &hash_len); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS && hash_len == SHA512_HASH_SZ, ESP_FAIL, error, TAG, + "Hash operation failed: status=%d, hash_len=%d", status, hash_len); + *len_key = hash_len; *bytes_key = hd->session_key; - *len_key = SHA512_HASH_SZ; free(bytes_S); esp_mpi_free(vu); @@ -583,73 +721,109 @@ error: free(hd->bytes_A); hd->bytes_A = NULL; } - return ESP_FAIL; + psa_hash_abort(&hash_op); + return ret; } esp_err_t esp_srp_exchange_proofs(esp_srp_handle_t *hd, char *username, uint16_t username_len, char *bytes_user_proof, char *bytes_host_proof) { + esp_err_t ret = ESP_FAIL; + + /* Add validation for input parameters */ + if (!hd || !username || !bytes_user_proof || !bytes_host_proof) { + ESP_LOGE(TAG, "Invalid parameters: hd=%p, username=%p, bytes_user_proof=%p, bytes_host_proof=%p", + hd, username, bytes_user_proof, bytes_host_proof); + return ESP_ERR_INVALID_ARG; + } + + if (username_len <= 0) { + ESP_LOGE(TAG, "Invalid username length: %d", username_len); + return ESP_ERR_INVALID_ARG; + } + + /* Check if the necessary SRP parameters and session key are initialized */ + if (!hd->bytes_A || !hd->bytes_B || !hd->bytes_s || !hd->session_key) { + ESP_LOGE(TAG, "SRP exchange not properly initialized: A=%p, B=%p, s=%p, key=%p", + hd->bytes_A, hd->bytes_B, hd->bytes_s, hd->session_key); + return ESP_ERR_INVALID_STATE; + } + /* First calculate M */ unsigned char hash_n[SHA512_HASH_SZ]; unsigned char hash_g[SHA512_HASH_SZ]; unsigned char hash_n_xor_g[SHA512_HASH_SZ]; int i; - + char *s = NULL; unsigned char hash_I[SHA512_HASH_SZ]; - mbedtls_sha512((unsigned char *)username, username_len, (unsigned char *)hash_I, 0); - mbedtls_sha512((unsigned char *)hd->bytes_n, hd->len_n, (unsigned char *)hash_n, 0); + size_t hash_len = 0; + psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT; + psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + ESP_RETURN_ON_FALSE(status == PSA_SUCCESS, ESP_FAIL, TAG, "Failed to setup hash operation: %d", status); + psa_hash_update(&hash_op, (unsigned char *)username, username_len); + status = psa_hash_finish(&hash_op, (unsigned char *)hash_I, SHA512_HASH_SZ, &hash_len); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS && hash_len == SHA512_HASH_SZ, ESP_FAIL, error, TAG, + "Hash operation failed: status=%d, hash_len=%d", status, hash_len); + + status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + ESP_RETURN_ON_FALSE(status == PSA_SUCCESS, ESP_FAIL, TAG, "Failed to setup hash operation: %d", status); + + psa_hash_update(&hash_op, (unsigned char *)hd->bytes_n, hd->len_n); + status = psa_hash_finish(&hash_op, (unsigned char *)hash_n, SHA512_HASH_SZ, &hash_len); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS && hash_len == SHA512_HASH_SZ, ESP_FAIL, error, TAG, + "Hash operation failed: status=%d, hash_len=%d", status, hash_len); int pad_len = hd->len_n - hd->len_g; - char *s = calloc(pad_len, sizeof(char)); - if (!s) { - return ESP_ERR_NO_MEM; - } + s = calloc(pad_len, sizeof(char)); + ESP_RETURN_ON_FALSE(s, ESP_ERR_NO_MEM, TAG, "Failed to allocate memory"); - mbedtls_sha512_context ctx; - mbedtls_sha512_init(&ctx); - mbedtls_sha512_starts(&ctx, 0); - mbedtls_sha512_update(&ctx, (unsigned char *)s, pad_len); - mbedtls_sha512_update(&ctx, (unsigned char *)hd->bytes_g, hd->len_g); - mbedtls_sha512_finish(&ctx, hash_g); - mbedtls_sha512_free(&ctx); + status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + ESP_RETURN_ON_FALSE(status == PSA_SUCCESS, ESP_FAIL, TAG, "Failed to setup hash operation: %d", status); + psa_hash_update(&hash_op, (unsigned char *)s, pad_len); + psa_hash_update(&hash_op, (unsigned char *)hd->bytes_g, hd->len_g); + status = psa_hash_finish(&hash_op, (unsigned char *)hash_g, SHA512_HASH_SZ, &hash_len); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS && hash_len == SHA512_HASH_SZ, ESP_FAIL, error, TAG, + "Hash operation failed: status=%d, hash_len=%d", status, hash_len); for (i = 0; i < SHA512_HASH_SZ; i++) { hash_n_xor_g[i] = hash_n[i] ^ hash_g[i]; } unsigned char digest[SHA512_HASH_SZ]; - mbedtls_sha512_init(&ctx); - mbedtls_sha512_starts(&ctx, 0); - mbedtls_sha512_update(&ctx, hash_n_xor_g, SHA512_HASH_SZ); - mbedtls_sha512_update(&ctx, hash_I, SHA512_HASH_SZ); - mbedtls_sha512_update(&ctx, (unsigned char *)hd->bytes_s, hd->len_s); - mbedtls_sha512_update(&ctx, (unsigned char *)hd->bytes_A, hd->len_A); - mbedtls_sha512_update(&ctx, (unsigned char *)hd->bytes_B, hd->len_B); - mbedtls_sha512_update(&ctx, (unsigned char *)hd->session_key, SHA512_HASH_SZ); - mbedtls_sha512_finish(&ctx, digest); - mbedtls_sha512_free(&ctx); + status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + ESP_RETURN_ON_FALSE(status == PSA_SUCCESS, ESP_FAIL, TAG, "Failed to setup hash operation: %d", status); + psa_hash_update(&hash_op, hash_n_xor_g, SHA512_HASH_SZ); + psa_hash_update(&hash_op, hash_I, SHA512_HASH_SZ); + psa_hash_update(&hash_op, (unsigned char *)hd->bytes_s, hd->len_s); + psa_hash_update(&hash_op, (unsigned char *)hd->bytes_A, hd->len_A); + psa_hash_update(&hash_op, (unsigned char *)hd->bytes_B, hd->len_B); + psa_hash_update(&hash_op, (unsigned char *)hd->session_key, SHA512_HASH_SZ); + status = psa_hash_finish(&hash_op, digest, SHA512_HASH_SZ, &hash_len); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS && hash_len == SHA512_HASH_SZ, ESP_FAIL, error, TAG, + "Hash operation failed: status=%d, hash_len=%d", status, hash_len); ESP_LOGD(TAG, "M ->"); ESP_LOG_BUFFER_HEX_LEVEL(TAG, (char *)digest, sizeof(digest), ESP_LOG_DEBUG); - if (memcmp(bytes_user_proof, digest, SHA512_HASH_SZ) != 0) { - free(s); - return ESP_FAIL; - } + ESP_GOTO_ON_FALSE(memcmp(bytes_user_proof, digest, SHA512_HASH_SZ) == 0, ESP_FAIL, error, TAG, "Failed to validate user proof"); /* M is now validated, let's proceed to H(AMK) */ - mbedtls_sha512_init(&ctx); - mbedtls_sha512_starts(&ctx, 0); - mbedtls_sha512_update(&ctx, (unsigned char *)hd->bytes_A, hd->len_A); - mbedtls_sha512_update(&ctx, digest, SHA512_HASH_SZ); - mbedtls_sha512_update(&ctx, (unsigned char *)hd->session_key, SHA512_HASH_SZ); - mbedtls_sha512_finish(&ctx, (unsigned char *)bytes_host_proof); - mbedtls_sha512_free(&ctx); + status = psa_hash_setup(&hash_op, PSA_ALG_SHA_512); + ESP_RETURN_ON_FALSE(status == PSA_SUCCESS, ESP_FAIL, TAG, "Failed to setup hash operation: %d", status); + psa_hash_update(&hash_op, (unsigned char *)hd->bytes_A, hd->len_A); + psa_hash_update(&hash_op, digest, SHA512_HASH_SZ); + psa_hash_update(&hash_op, (unsigned char *)hd->session_key, SHA512_HASH_SZ); + status = psa_hash_finish(&hash_op, (unsigned char *)bytes_host_proof, SHA512_HASH_SZ, &hash_len); + ESP_GOTO_ON_FALSE(status == PSA_SUCCESS && hash_len == SHA512_HASH_SZ, ESP_FAIL, error, TAG, + "Hash operation failed: status=%d, hash_len=%d", status, hash_len); ESP_LOGD(TAG, "AMK ->"); ESP_LOG_BUFFER_HEX_LEVEL(TAG, (char *)bytes_host_proof, SHA512_HASH_SZ, ESP_LOG_DEBUG); + ret = ESP_OK; +error: + psa_hash_abort(&hash_op); if (s) { free(s); } - return ESP_OK; + return ret; } diff --git a/components/protocomm/src/crypto/srp6a/esp_srp_mpi.c b/components/protocomm/src/crypto/srp6a/esp_srp_mpi.c index 2cb60e4ee97..7798268dea8 100644 --- a/components/protocomm/src/crypto/srp6a/esp_srp_mpi.c +++ b/components/protocomm/src/crypto/srp6a/esp_srp_mpi.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "esp_srp_mpi.h" esp_mpi_t *esp_mpi_new(void) diff --git a/components/protocomm/src/crypto/srp6a/esp_srp_mpi.h b/components/protocomm/src/crypto/srp6a/esp_srp_mpi.h index 46f07bc9ee0..62095930bb9 100644 --- a/components/protocomm/src/crypto/srp6a/esp_srp_mpi.h +++ b/components/protocomm/src/crypto/srp6a/esp_srp_mpi.h @@ -9,9 +9,7 @@ #include "string.h" #include "stdio.h" -#include "mbedtls/bignum.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" +#include "mbedtls/private/bignum.h" #include "esp_random.h" #ifdef __cplusplus diff --git a/components/protocomm/src/security/security1.c b/components/protocomm/src/security/security1.c index da707ea1753..9afb27b03c0 100644 --- a/components/protocomm/src/security/security1.c +++ b/components/protocomm/src/security/security1.c @@ -25,13 +25,9 @@ #define ACCESS_ECDH(S, var) S->MBEDTLS_PRIVATE(ctx).MBEDTLS_PRIVATE(mbed_ecdh).MBEDTLS_PRIVATE(var) #endif -#include -#include -#include -#include -#include #include #include +#include "psa/crypto.h" #include #include @@ -65,26 +61,21 @@ typedef struct session { uint8_t sym_key[PUBLIC_KEY_LEN]; uint8_t rand[SZ_RANDOM]; + /* Operation counter for CTR mode nonce */ + uint32_t op_counter; + /* mbedtls context data for AES */ - mbedtls_aes_context ctx_aes; + psa_cipher_operation_t ctx_aes; + psa_key_id_t key_id; + psa_key_id_t key_id_sym; unsigned char stb[16]; size_t nc_off; } session_t; -static void flip_endian(uint8_t *data, size_t len) -{ - uint8_t swp_buf; - for (int i = 0; i < len/2; i++) { - swp_buf = data[i]; - data[i] = data[len - i - 1]; - data[len - i - 1] = swp_buf; - } -} - static void hexdump(const char *msg, uint8_t *buf, int len) { ESP_LOGD(TAG, "%s:", msg); - ESP_LOG_BUFFER_HEX_LEVEL(TAG, buf, len, ESP_LOG_DEBUG); + ESP_LOG_BUFFER_HEX_LEVEL(TAG, buf, len, ESP_LOG_INFO); } static esp_err_t handle_session_command1(session_t *cur_session, @@ -93,8 +84,6 @@ static esp_err_t handle_session_command1(session_t *cur_session, { ESP_LOGD(TAG, "Request to handle setup1_command"); Sec1Payload *in = (Sec1Payload *) req->sec1; - uint8_t check_buf[PUBLIC_KEY_LEN]; - int mbed_err; if (cur_session->state != SESSION_STATE_CMD1) { ESP_LOGE(TAG, "Invalid state of session %d (expected %d)", SESSION_STATE_CMD1, cur_session->state); @@ -117,28 +106,55 @@ static esp_err_t handle_session_command1(session_t *cur_session, } /* Initialize crypto context */ - mbedtls_aes_init(&cur_session->ctx_aes); memset(cur_session->stb, 0, sizeof(cur_session->stb)); cur_session->nc_off = 0; + cur_session->op_counter = 0; - hexdump("Client verifier", in->sc1->client_verify_data.data, + hexdump("Data to decrypt", in->sc1->client_verify_data.data, in->sc1->client_verify_data.len); - mbed_err = mbedtls_aes_setkey_enc(&cur_session->ctx_aes, cur_session->sym_key, - sizeof(cur_session->sym_key)*8); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failure at mbedtls_aes_setkey_enc with error code : -0x%x", -mbed_err); - mbedtls_aes_free(&cur_session->ctx_aes); + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_algorithm_t alg = PSA_ALG_CTR; + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&key_attributes, alg); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_bits(&key_attributes, sizeof(cur_session->sym_key) * 8); + status = psa_import_key(&key_attributes, cur_session->sym_key, sizeof(cur_session->sym_key), &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_import_key failed with status=%d", status); + return ESP_FAIL; + } + cur_session->key_id_sym = key_id; + psa_reset_key_attributes(&key_attributes); + size_t output_len = 0; + size_t cipher_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES, alg, in->sc1->client_verify_data.len); + uint8_t check_buf[cipher_size]; + + cur_session->ctx_aes = psa_cipher_operation_init(); + status = psa_cipher_encrypt_setup(&cur_session->ctx_aes, key_id, alg); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_cipher_encrypt_setup failed with status=%d", status); + psa_cipher_abort(&cur_session->ctx_aes); + psa_destroy_key(key_id); + return ESP_FAIL; + } + status = psa_cipher_set_iv(&cur_session->ctx_aes, cur_session->rand, sizeof(cur_session->rand)); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_cipher_set_iv failed with status=%d", status); + psa_cipher_abort(&cur_session->ctx_aes); + psa_destroy_key(key_id); return ESP_FAIL; } - mbed_err = mbedtls_aes_crypt_ctr(&cur_session->ctx_aes, - PUBLIC_KEY_LEN, &cur_session->nc_off, - cur_session->rand, cur_session->stb, - in->sc1->client_verify_data.data, check_buf); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failure at mbedtls_aes_crypt_ctr with error code : -0x%x", -mbed_err); - mbedtls_aes_free(&cur_session->ctx_aes); + status = psa_cipher_update(&cur_session->ctx_aes, in->sc1->client_verify_data.data, + in->sc1->client_verify_data.len, check_buf, sizeof(check_buf), &output_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_cipher_update failed with status=%d", status); + psa_cipher_abort(&cur_session->ctx_aes); + psa_destroy_key(key_id); return ESP_FAIL; } @@ -148,7 +164,7 @@ static esp_err_t handle_session_command1(session_t *cur_session, if (mbedtls_ct_memcmp(check_buf, cur_session->device_pubkey, sizeof(cur_session->device_pubkey)) != 0) { ESP_LOGE(TAG, "Key mismatch. Close connection"); - mbedtls_aes_free(&cur_session->ctx_aes); + psa_destroy_key(key_id); if (esp_event_post(PROTOCOMM_SECURITY_SESSION_EVENT, PROTOCOMM_SECURITY_SESSION_CREDENTIALS_MISMATCH, NULL, 0, portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post credential mismatch event"); } @@ -161,7 +177,6 @@ static esp_err_t handle_session_command1(session_t *cur_session, ESP_LOGE(TAG, "Error allocating memory for response1"); free(out); free(out_resp); - mbedtls_aes_free(&cur_session->ctx_aes); return ESP_ERR_NO_MEM; } @@ -174,20 +189,14 @@ static esp_err_t handle_session_command1(session_t *cur_session, ESP_LOGE(TAG, "Error allocating ciphertext buffer"); free(out); free(out_resp); - mbedtls_aes_free(&cur_session->ctx_aes); return ESP_ERR_NO_MEM; } - mbed_err = mbedtls_aes_crypt_ctr(&cur_session->ctx_aes, - PUBLIC_KEY_LEN, &cur_session->nc_off, - cur_session->rand, cur_session->stb, - cur_session->client_pubkey, outbuf); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failure at mbedtls_aes_crypt_ctr with error code : -0x%x", -mbed_err); + size_t outlen = 0; + status = psa_cipher_update(&cur_session->ctx_aes, cur_session->client_pubkey, sizeof(cur_session->client_pubkey), outbuf, PUBLIC_KEY_LEN, &outlen); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed at psa_cipher_update with error code : %d", status); free(outbuf); - free(out); - free(out_resp); - mbedtls_aes_free(&cur_session->ctx_aes); return ESP_FAIL; } @@ -221,7 +230,6 @@ static esp_err_t handle_session_command0(session_t *cur_session, ESP_LOGD(TAG, "Request to handle setup0_command"); Sec1Payload *in = (Sec1Payload *) req->sec1; esp_err_t ret; - int mbed_err; if (cur_session->state != SESSION_STATE_CMD0) { ESP_LOGW(TAG, "Invalid state of session %d (expected %d). Restarting session.", @@ -237,55 +245,30 @@ static esp_err_t handle_session_command0(session_t *cur_session, return ESP_ERR_INVALID_ARG; } - mbedtls_ecdh_context *ctx_server = malloc(sizeof(mbedtls_ecdh_context)); - mbedtls_entropy_context *entropy = malloc(sizeof(mbedtls_entropy_context)); - mbedtls_ctr_drbg_context *ctr_drbg = malloc(sizeof(mbedtls_ctr_drbg_context)); - if (!ctx_server || !entropy || !ctr_drbg) { - ESP_LOGE(TAG, "Failed to allocate memory for mbedtls context"); - free(ctx_server); - free(entropy); - free(ctr_drbg); - return ESP_ERR_NO_MEM; + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)); + psa_set_key_bits(&key_attributes, 255); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + status = psa_generate_key(&key_attributes, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_generate_key failed with status=%d", status); + psa_reset_key_attributes(&key_attributes); + return ESP_FAIL; } + psa_reset_key_attributes(&key_attributes); + size_t olen = 0; - mbedtls_ecdh_init(ctx_server); - mbedtls_ecdh_setup(ctx_server, MBEDTLS_ECP_DP_CURVE25519); - mbedtls_ctr_drbg_init(ctr_drbg); - mbedtls_entropy_init(entropy); - - mbed_err = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func, - entropy, NULL, 0); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ctr_drbg_seed with error code : -0x%x", -mbed_err); - ret = ESP_FAIL; - goto exit_cmd0; + status = psa_export_public_key(key_id, cur_session->device_pubkey, PUBLIC_KEY_LEN, &olen); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_export_public_key failed with status=%d", status); + psa_reset_key_attributes(&key_attributes); + return ESP_FAIL; } - mbed_err = mbedtls_ecp_group_load(ACCESS_ECDH(&ctx_server, grp), MBEDTLS_ECP_DP_CURVE25519); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ecp_group_load with error code : -0x%x", -mbed_err); - ret = ESP_FAIL; - goto exit_cmd0; - } - - mbed_err = mbedtls_ecdh_gen_public(ACCESS_ECDH(&ctx_server, grp), ACCESS_ECDH(&ctx_server, d), ACCESS_ECDH(&ctx_server, Q), - mbedtls_ctr_drbg_random, ctr_drbg); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ecdh_gen_public with error code : -0x%x", -mbed_err); - ret = ESP_FAIL; - goto exit_cmd0; - } - - mbed_err = mbedtls_mpi_write_binary(ACCESS_ECDH(&ctx_server, Q).MBEDTLS_PRIVATE(X), - cur_session->device_pubkey, - PUBLIC_KEY_LEN); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_write_binary with error code : -0x%x", -mbed_err); - ret = ESP_FAIL; - goto exit_cmd0; - } - flip_endian(cur_session->device_pubkey, PUBLIC_KEY_LEN); - memcpy(cur_session->client_pubkey, in->sc0->client_pubkey.data, PUBLIC_KEY_LEN); uint8_t *dev_pubkey = cur_session->device_pubkey; @@ -293,49 +276,48 @@ static esp_err_t handle_session_command0(session_t *cur_session, hexdump("Device pubkey", dev_pubkey, PUBLIC_KEY_LEN); hexdump("Client pubkey", cli_pubkey, PUBLIC_KEY_LEN); - mbed_err = mbedtls_mpi_lset(ACCESS_ECDH(&ctx_server, Qp).MBEDTLS_PRIVATE(Z), 1); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_lset with error code : -0x%x", -mbed_err); + status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, cur_session->client_pubkey, PUBLIC_KEY_LEN, + cur_session->sym_key, sizeof(cur_session->sym_key), &olen); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_raw_key_agreement failed with status=%d", status); ret = ESP_FAIL; goto exit_cmd0; } - - flip_endian(cur_session->client_pubkey, PUBLIC_KEY_LEN); - mbed_err = mbedtls_mpi_read_binary(ACCESS_ECDH(&ctx_server, Qp).MBEDTLS_PRIVATE(X), cli_pubkey, PUBLIC_KEY_LEN); - flip_endian(cur_session->client_pubkey, PUBLIC_KEY_LEN); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_read_binary with error code : -0x%x", -mbed_err); + if (olen != sizeof(cur_session->sym_key)) { + ESP_LOGE(TAG, "psa_raw_key_agreement output length mismatch: expected %zu, got %zu", + sizeof(cur_session->sym_key), olen); ret = ESP_FAIL; goto exit_cmd0; } - - mbed_err = mbedtls_ecdh_compute_shared(ACCESS_ECDH(&ctx_server, grp), ACCESS_ECDH(&ctx_server, z), ACCESS_ECDH(&ctx_server, Qp), - ACCESS_ECDH(&ctx_server, d), mbedtls_ctr_drbg_random, ctr_drbg); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ecdh_compute_shared with error code : -0x%x", -mbed_err); - ret = ESP_FAIL; - goto exit_cmd0; - } - - mbed_err = mbedtls_mpi_write_binary(ACCESS_ECDH(&ctx_server, z), cur_session->sym_key, PUBLIC_KEY_LEN); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_write_binary with error code : -0x%x", -mbed_err); - ret = ESP_FAIL; - goto exit_cmd0; - } - flip_endian(cur_session->sym_key, PUBLIC_KEY_LEN); + cur_session->key_id = key_id; if (pop != NULL && pop->data != NULL && pop->len != 0) { ESP_LOGD(TAG, "Adding proof of possession"); uint8_t sha_out[PUBLIC_KEY_LEN]; - mbed_err = mbedtls_sha256((const unsigned char *) pop->data, pop->len, sha_out, 0); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_sha256_ret with error code : -0x%x", -mbed_err); + psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT; + status = psa_hash_setup(&hash_operation, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_hash_setup failed with status=%d", status); ret = ESP_FAIL; goto exit_cmd0; } + status = psa_hash_update(&hash_operation, pop->data, pop->len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_hash_update failed with status=%d", status); + psa_hash_abort(&hash_operation); + ret = ESP_FAIL; + goto exit_cmd0; + } + + status = psa_hash_finish(&hash_operation, sha_out, sizeof(sha_out), &olen); + if (status != PSA_SUCCESS || olen != sizeof(sha_out)) { + ESP_LOGE(TAG, "psa_hash_finish failed with status=%d", status); + psa_hash_abort(&hash_operation); + ret = ESP_FAIL; + goto exit_cmd0; + } for (int i = 0; i < PUBLIC_KEY_LEN; i++) { cur_session->sym_key[i] ^= sha_out[i]; } @@ -343,9 +325,9 @@ static esp_err_t handle_session_command0(session_t *cur_session, hexdump("Shared key", cur_session->sym_key, PUBLIC_KEY_LEN); - mbed_err = mbedtls_ctr_drbg_random(ctr_drbg, cur_session->rand, SZ_RANDOM); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ctr_drbg_random with error code : -0x%x", -mbed_err); + status = psa_generate_random(cur_session->rand, SZ_RANDOM); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_generate_random failed with status=%d", status); ret = ESP_FAIL; goto exit_cmd0; } @@ -386,15 +368,11 @@ static esp_err_t handle_session_command0(session_t *cur_session, ret = ESP_OK; exit_cmd0: - mbedtls_ecdh_free(ctx_server); - free(ctx_server); - - mbedtls_ctr_drbg_free(ctr_drbg); - free(ctr_drbg); - - mbedtls_entropy_free(entropy); - free(entropy); - + // Clean up the key_id if it wasn't stored in the session + // This happens when key agreement fails before cur_session->key_id is assigned + if (ret != ESP_OK && key_id != 0 && cur_session->key_id != key_id) { + psa_destroy_key(key_id); + } return ret; } @@ -473,9 +451,21 @@ static esp_err_t sec1_close_session(protocomm_security_handle_t handle, uint32_t return ESP_ERR_INVALID_STATE; } - if (cur_session->state == SESSION_STATE_DONE) { - /* Free AES context data */ - mbedtls_aes_free(&cur_session->ctx_aes); + if (cur_session->key_id != 0) { + psa_status_t status = psa_destroy_key(cur_session->key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_destroy_key failed with status=%d", status); + } + } + if (cur_session->key_id_sym != 0) { + psa_status_t status = psa_destroy_key(cur_session->key_id_sym); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_destroy_key failed with status=%d", status); + } + } + psa_status_t status = psa_cipher_abort(&cur_session->ctx_aes); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_cipher_abort failed with status=%d", status); } memset(cur_session, 0, sizeof(session_t)); @@ -525,7 +515,7 @@ static esp_err_t sec1_cleanup(protocomm_security_handle_t handle) return ESP_OK; } -static esp_err_t sec1_decrypt(protocomm_security_handle_t handle, +static esp_err_t sec1_crypt(protocomm_security_handle_t handle, uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen) @@ -552,10 +542,11 @@ static esp_err_t sec1_decrypt(protocomm_security_handle_t handle, return ESP_ERR_NO_MEM; } - int ret = mbedtls_aes_crypt_ctr(&cur_session->ctx_aes, inlen, &cur_session->nc_off, - cur_session->rand, cur_session->stb, inbuf, *outbuf); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_aes_crypt_ctr with error code : %d", ret); + size_t out_len = 0; + psa_status_t status = psa_cipher_update(&cur_session->ctx_aes, inbuf, inlen, *outbuf, *outlen, &out_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_cipher_update failed with status=%d", status); + free(*outbuf); return ESP_FAIL; } return ESP_OK; @@ -624,6 +615,6 @@ const protocomm_security_t protocomm_security1 = { .new_transport_session = sec1_new_session, .close_transport_session = sec1_close_session, .security_req_handler = sec1_req_handler, - .encrypt = sec1_decrypt, /* Encrypt == decrypt for AES-CTR */ - .decrypt = sec1_decrypt, + .encrypt = sec1_crypt, /* Encrypt == decrypt for AES-CTR */ + .decrypt = sec1_crypt, }; diff --git a/components/protocomm/src/security/security2.c b/components/protocomm/src/security/security2.c index 326bb65d7ff..9b145fcf2f0 100644 --- a/components/protocomm/src/security/security2.c +++ b/components/protocomm/src/security/security2.c @@ -12,10 +12,8 @@ #include #include -#include #include -#include -#include +#include "psa/crypto.h" #include #include @@ -64,8 +62,8 @@ typedef struct session { char *session_key; uint16_t session_key_len; uint8_t iv[AES_GCM_IV_SIZE]; - /* mbedtls context data for AES-GCM */ - mbedtls_gcm_context ctx_gcm; + /* PSA key for AES-GCM */ + psa_key_id_t key_id; esp_srp_handle_t *srp_hd; } session_t; @@ -215,7 +213,6 @@ static esp_err_t handle_session_command1(session_t *cur_session, { ESP_LOGD(TAG, "Request to handle setup1_command"); Sec2Payload *in = (Sec2Payload *) req->sec2; - int mbed_err = -0x0001; if (cur_session->state != SESSION_STATE_CMD1) { ESP_LOGE(TAG, "Invalid state of session %d (expected %d)", SESSION_STATE_CMD1, cur_session->state); @@ -242,24 +239,11 @@ static esp_err_t handle_session_command1(session_t *cur_session, } hexdump("Device proof", device_proof, CLIENT_PROOF_LEN); - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; - - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_init(&ctr_drbg); - - int ret; - ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0); - if (ret != 0) { - ESP_LOGE(TAG, "Failed to seed random number generator"); - free(device_proof); - return ESP_FAIL; - } - aes_gcm_iv_t *iv = (aes_gcm_iv_t *) cur_session->iv; - ret = mbedtls_ctr_drbg_random(&ctr_drbg, iv->session_id, SESSION_ID_LEN); - if (ret != 0) { - ESP_LOGE(TAG, "Failed to generate random number"); + psa_status_t status; + status = psa_generate_random(iv->session_id, SESSION_ID_LEN); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_generate_random failed with status=%d", status); free(device_proof); return ESP_FAIL; } @@ -268,16 +252,28 @@ static esp_err_t handle_session_command1(session_t *cur_session, hexdump("Initialization vector", (char *)cur_session->iv, AES_GCM_IV_SIZE); - /* Initialize crypto context */ - mbedtls_gcm_init(&cur_session->ctx_gcm); - - mbed_err = mbedtls_gcm_setkey(&cur_session->ctx_gcm, MBEDTLS_CIPHER_ID_AES, (unsigned char *)cur_session->session_key, AES_GCM_KEY_LEN); - if (mbed_err != 0) { - ESP_LOGE(TAG, "Failure at mbedtls_gcm_setkey_enc with error code : -0x%x", -mbed_err); + /* Initialize AES-GCM key */ + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, AES_GCM_TAG_LEN); + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, AES_GCM_KEY_LEN); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&key_attributes, alg); + /* Use first 32 bytes (256 bits) of the session key for AES-GCM */ + size_t aes_key_bytes = AES_GCM_KEY_LEN / 8; + if (cur_session->session_key_len < aes_key_bytes) { + ESP_LOGE(TAG, "Session key too short: %d bytes (need at least %zu bytes)", cur_session->session_key_len, aes_key_bytes); free(device_proof); - mbedtls_gcm_free(&cur_session->ctx_gcm); return ESP_FAIL; } + status = psa_import_key(&key_attributes, (uint8_t *)cur_session->session_key, aes_key_bytes, &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_import_key failed with status=%d", status); + free(device_proof); + return ESP_FAIL; + } + cur_session->key_id = key_id; Sec2Payload *out = (Sec2Payload *) malloc(sizeof(Sec2Payload)); S2SessionResp1 *out_resp = (S2SessionResp1 *) malloc(sizeof(S2SessionResp1)); @@ -286,7 +282,7 @@ static esp_err_t handle_session_command1(session_t *cur_session, free(device_proof); free(out); free(out_resp); - mbedtls_gcm_free(&cur_session->ctx_gcm); + psa_destroy_key(key_id); return ESP_ERR_NO_MEM; } @@ -390,8 +386,9 @@ static esp_err_t sec2_close_session(protocomm_security_handle_t handle, uint32_t } if (cur_session->state == SESSION_STATE_DONE) { - /* Free GCM context data */ - mbedtls_gcm_free(&cur_session->ctx_gcm); + /* Destroy the AES-GCM key */ + psa_destroy_key(cur_session->key_id); + cur_session->key_id = 0; } free(cur_session->username); @@ -480,16 +477,27 @@ static esp_err_t sec2_encrypt(protocomm_security_handle_t handle, ESP_LOGE(TAG, "Failed to allocate encrypt buf len %d", *outlen); return ESP_ERR_NO_MEM; } - uint8_t gcm_tag[AES_GCM_TAG_LEN]; - int ret = mbedtls_gcm_crypt_and_tag(&cur_session->ctx_gcm, MBEDTLS_GCM_ENCRYPT, inlen, cur_session->iv, - AES_GCM_IV_SIZE, NULL, 0, inbuf, - *outbuf, AES_GCM_TAG_LEN, gcm_tag); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_gcm_crypt_and_tag with error code : %d", ret); + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, AES_GCM_TAG_LEN); + size_t out_len = 0; + + status = psa_aead_encrypt(cur_session->key_id, alg, + cur_session->iv, AES_GCM_IV_SIZE, + NULL, 0, /* No additional data */ + inbuf, inlen, + *outbuf, *outlen, &out_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_aead_encrypt failed with status=%d", status); + free(*outbuf); + return ESP_FAIL; + } + + if (out_len != *outlen) { + ESP_LOGE(TAG, "psa_aead_encrypt output length mismatch: expected %zd, got %zu", *outlen, out_len); + free(*outbuf); return ESP_FAIL; } - memcpy(*outbuf + inlen, gcm_tag, AES_GCM_TAG_LEN); /* Increment counter value for next operation */ sec2_gcm_iv_counter_increment(cur_session->iv); @@ -531,10 +539,24 @@ static esp_err_t sec2_decrypt(protocomm_security_handle_t handle, return ESP_ERR_NO_MEM; } - int ret = mbedtls_gcm_auth_decrypt(&cur_session->ctx_gcm, inlen - AES_GCM_TAG_LEN, cur_session->iv, - AES_GCM_IV_SIZE, NULL, 0, inbuf + (inlen - AES_GCM_TAG_LEN), AES_GCM_TAG_LEN, inbuf, *outbuf); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_gcm_auth_decrypt : %d", ret); + psa_status_t status; + psa_algorithm_t alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, AES_GCM_TAG_LEN); + size_t out_len = 0; + + status = psa_aead_decrypt(cur_session->key_id, alg, + cur_session->iv, AES_GCM_IV_SIZE, + NULL, 0, /* No additional data */ + inbuf, inlen, + *outbuf, *outlen, &out_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_aead_decrypt failed with status=%d", status); + free(*outbuf); + return ESP_FAIL; + } + + if (out_len != *outlen) { + ESP_LOGE(TAG, "psa_aead_decrypt output length mismatch: expected %zd, got %zu", *outlen, out_len); + free(*outbuf); return ESP_FAIL; } diff --git a/components/protocomm/test_apps/main/CMakeLists.txt b/components/protocomm/test_apps/main/CMakeLists.txt index 74dc603fa6a..e12000e0085 100644 --- a/components/protocomm/test_apps/main/CMakeLists.txt +++ b/components/protocomm/test_apps/main/CMakeLists.txt @@ -1,3 +1,4 @@ idf_component_register(SRC_DIRS "." PRIV_INCLUDE_DIRS "." - PRIV_REQUIRES cmock mbedtls protocomm protobuf-c test_utils unity) + PRIV_REQUIRES cmock mbedtls protocomm protobuf-c test_utils unity + WHOLE_ARCHIVE) diff --git a/components/protocomm/test_apps/main/app_main.c b/components/protocomm/test_apps/main/app_main.c new file mode 100644 index 00000000000..15f78695136 --- /dev/null +++ b/components/protocomm/test_apps/main/app_main.c @@ -0,0 +1,109 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" +#include "test_utils.h" +#include "memory_checks.h" +#include "esp_newlib.h" +#include "psa/crypto.h" +// #include "mbedtls/aes.h" +#if SOC_SHA_SUPPORT_PARALLEL_ENG +#include "sha/sha_parallel_engine.h" +#else +#include "sha/sha_core.h" +#endif +#include "bignum_impl.h" + +/* setUp runs before every test */ +void setUp(void) +{ +#if CONFIG_MBEDTLS_HARDWARE_SHA + // Execute esp_sha operation to allocate internal SHA semaphore (in case of ESP32) + // and initial DMA setup memory which is considered as leaked otherwise + const uint8_t input_buffer[64] = {0}; + uint8_t output_buffer[64]; +#if SOC_SHA_SUPPORT_SHA1 + esp_sha(SHA1, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA1 +#if SOC_SHA_SUPPORT_SHA256 + esp_sha(SHA2_256, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA256 +#if SOC_SHA_SUPPORT_SHA512 + esp_sha(SHA2_512, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA512 +#endif // CONFIG_MBEDTLS_HARDWARE_SHA + +#if defined(CONFIG_MBEDTLS_HARDWARE_MPI) + esp_mpi_enable_hardware_hw_op(); + esp_mpi_disable_hardware_hw_op(); +#endif // CONFIG_MBEDTLS_HARDWARE_MPI + +// #if SOC_AES_SUPPORTED + // Execute mbedtls_aes_init operation to allocate AES interrupt + // allocation memory which is considered as leak otherwise + const uint8_t plaintext[16] = {0}; + uint8_t ciphertext[32]; + const uint8_t key[16] = { 0 }; + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + status = psa_import_key(&attributes, key, sizeof(key), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + size_t output_len = 0; + status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, plaintext, sizeof(plaintext), ciphertext, sizeof(ciphertext), &output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + + const uint8_t plaintext_long[256] = {0}; + uint8_t ciphertext_long[272]; + output_len = 0; + status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, plaintext_long, sizeof(plaintext_long), ciphertext_long, sizeof(ciphertext_long), &output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + psa_destroy_key(key_id); + // Destroying the key again to get rid of nvs flash memory leak + // If the key doesn't exist, PSA looks for it in nvs and that + // allocates some memory which is considered as leak otherwise + psa_destroy_key(key_id); +// #endif // SOC_AES_SUPPORTED + + test_utils_record_free_mem(); + TEST_ESP_OK(test_utils_set_leak_level(50, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); + TEST_ESP_OK(test_utils_set_leak_level(50, ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_GENERAL)); +} + +/* tearDown runs after every test */ +void tearDown(void) +{ + /* some FreeRTOS stuff is cleaned up by idle task */ + vTaskDelay(5); + + /* clean up some of the newlib's lazy allocations */ + esp_reent_cleanup(); + + // mbedtls_psa_crypto_free(); + + /* check if unit test has caused heap corruption in any heap */ + TEST_ASSERT_MESSAGE( heap_caps_check_integrity(MALLOC_CAP_INVALID, true), "The test has corrupted the heap"); + + test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), + test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); +} + +static void test_task(void *pvParameters) +{ + vTaskDelay(2); /* Delay a bit to let the main task be deleted */ + unity_run_menu(); +} + +void app_main(void) +{ + xTaskCreatePinnedToCore(test_task, "testTask", CONFIG_UNITY_FREERTOS_STACK_SIZE, NULL, CONFIG_UNITY_FREERTOS_PRIORITY, NULL, CONFIG_UNITY_FREERTOS_CPU); +} diff --git a/components/protocomm/test_apps/main/test_protocomm.c b/components/protocomm/test_apps/main/test_protocomm.c index 5ec35485841..a056597cc32 100644 --- a/components/protocomm/test_apps/main/test_protocomm.c +++ b/components/protocomm/test_apps/main/test_protocomm.c @@ -1,9 +1,11 @@ /* - * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "psa/crypto_struct.h" +#include "psa/crypto_types.h" #include #include #include @@ -28,13 +30,9 @@ #define ACCESS_ECDH(S, var) S.MBEDTLS_PRIVATE(ctx).MBEDTLS_PRIVATE(mbed_ecdh).MBEDTLS_PRIVATE(var) #endif -#include -#include -#include -#include -#include +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include - +#include "psa/crypto.h" #include #include #include @@ -62,15 +60,15 @@ typedef struct { uint8_t sym_key[PUBLIC_KEY_LEN]; uint8_t rand[SZ_RANDOM]; - /* mbedtls context data for Curve25519 */ - mbedtls_ecdh_context ctx_client; - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; - /* mbedtls context data for AES */ - mbedtls_aes_context ctx_aes; + psa_cipher_operation_t ctx_aes; + psa_key_id_t client_key_id; + psa_key_id_t key_id; unsigned char stb[16]; size_t nc_off; + + /* Operation counter for CTR mode nonce */ + uint32_t op_counter; } session_t; static const char *TAG = "protocomm_test"; @@ -80,16 +78,6 @@ static const protocomm_security_t *test_sec = NULL; protocomm_security_handle_t sec_inst = NULL; static uint32_t test_priv_data = 1234; -static void flip_endian(uint8_t *data, size_t len) -{ - uint8_t swp_buf; - for (int i = 0; i < len/2; i++) { - swp_buf = data[i]; - data[i] = data[len - i - 1]; - data[len - i - 1] = swp_buf; - } -} - static void hexdump(const char *msg, uint8_t *buf, int len) { ESP_LOGI(TAG, "%s:", msg); @@ -142,7 +130,6 @@ static esp_err_t verify_response0(session_t *session, SessionData *resp) return ESP_ERR_INVALID_ARG; } - int ret; Sec1Payload *in = (Sec1Payload *) resp->sec1; if (in->sr0->device_pubkey.len != PUBLIC_KEY_LEN) { @@ -159,50 +146,39 @@ static esp_err_t verify_response0(session_t *session, SessionData *resp) uint8_t *dev_pubkey = session->device_pubkey; memcpy(session->device_pubkey, in->sr0->device_pubkey.data, in->sr0->device_pubkey.len); - hexdump("Device pubkey", dev_pubkey, PUBLIC_KEY_LEN); - hexdump("Client pubkey", cli_pubkey, PUBLIC_KEY_LEN); + hexdump("Device pubkey0", dev_pubkey, PUBLIC_KEY_LEN); + hexdump("Client pubkey0", cli_pubkey, PUBLIC_KEY_LEN); - ret = mbedtls_mpi_lset(ACCESS_ECDH(&session->ctx_client, Qp).MBEDTLS_PRIVATE(Z), 1); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_lset with error code : %d", ret); + size_t olen = 0; + psa_status_t status = psa_raw_key_agreement( + PSA_ALG_ECDH, session->client_key_id, dev_pubkey, + PUBLIC_KEY_LEN, session->sym_key, sizeof(session->sym_key), &olen); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed at psa_raw_key_agreement with error code : %d", status); return ESP_FAIL; } - flip_endian(session->device_pubkey, PUBLIC_KEY_LEN); - ret = mbedtls_mpi_read_binary(ACCESS_ECDH(&session->ctx_client, Qp).MBEDTLS_PRIVATE(X), dev_pubkey, PUBLIC_KEY_LEN); - flip_endian(session->device_pubkey, PUBLIC_KEY_LEN); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_read_binary with error code : %d", ret); - return ESP_FAIL; - } - - ret = mbedtls_ecdh_compute_shared(ACCESS_ECDH(&session->ctx_client, grp), - ACCESS_ECDH(&session->ctx_client, z), - ACCESS_ECDH(&session->ctx_client, Qp), - ACCESS_ECDH(&session->ctx_client, d), - mbedtls_ctr_drbg_random, - &session->ctr_drbg); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ecdh_compute_shared with error code : %d", ret); - return ESP_FAIL; - } - - ret = mbedtls_mpi_write_binary(ACCESS_ECDH(&session->ctx_client, z), session->sym_key, PUBLIC_KEY_LEN); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_write_binary with error code : %d", ret); - return ESP_FAIL; - } - flip_endian(session->sym_key, PUBLIC_KEY_LEN); - const protocomm_security1_params_t *pop = session->pop; if (pop != NULL && pop->data != NULL && pop->len != 0) { ESP_LOGD(TAG, "Adding proof of possession"); uint8_t sha_out[PUBLIC_KEY_LEN]; - ret = mbedtls_sha256((const unsigned char *) pop->data, pop->len, sha_out, 0); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_sha256_ret with error code : %d", ret); - return ESP_FAIL; + psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT; + status = psa_hash_setup(&hash_operation, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_hash_setup failed with status=%d", status); + } + + status = psa_hash_update(&hash_operation, pop->data, pop->len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_hash_update failed with status=%d", status); + psa_hash_abort(&hash_operation); + } + + status = psa_hash_finish(&hash_operation, sha_out, sizeof(sha_out), &olen); + if (status != PSA_SUCCESS || olen != sizeof(sha_out)) { + ESP_LOGE(TAG, "psa_hash_finish failed with status=%d", status); + psa_hash_abort(&hash_operation); } for (int i = 0; i < PUBLIC_KEY_LEN; i++) { @@ -219,7 +195,6 @@ static esp_err_t verify_response0(session_t *session, SessionData *resp) static esp_err_t prepare_command1(session_t *session, SessionData *req) { - int ret; uint8_t *outbuf = (uint8_t *) malloc(PUBLIC_KEY_LEN); if (!outbuf) { ESP_LOGE(TAG, "Error allocating ciphertext buffer"); @@ -227,26 +202,44 @@ static esp_err_t prepare_command1(session_t *session, SessionData *req) } /* Initialise crypto context */ - mbedtls_aes_init(&session->ctx_aes); - memset(session->stb, 0, sizeof(session->stb)); - session->nc_off = 0; - - ret = mbedtls_aes_setkey_enc(&session->ctx_aes, session->sym_key, - sizeof(session->sym_key)*8); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_aes_setkey_enc with error code : %d", ret); + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; + psa_algorithm_t alg = PSA_ALG_CTR; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_algorithm(&key_attributes, alg); + status = psa_import_key(&key_attributes, session->sym_key, sizeof(session->sym_key), &key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed at psa_import_key with error code : %d", status); + free(outbuf); + return ESP_FAIL; + } + psa_reset_key_attributes(&key_attributes); + session->ctx_aes = psa_cipher_operation_init(); + status = psa_cipher_encrypt_setup(&session->ctx_aes, key_id, alg); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed at psa_cipher_encrypt_setup with error code : %d", status); + free(outbuf); + return ESP_FAIL; + } + status = psa_cipher_set_iv(&session->ctx_aes, session->rand, sizeof(session->rand)); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed at psa_cipher_set_iv with error code : %d", status); + free(outbuf); + return ESP_FAIL; + } + size_t outlen = 0; + status = psa_cipher_update(&session->ctx_aes, session->device_pubkey, sizeof(session->device_pubkey), outbuf, PUBLIC_KEY_LEN, &outlen); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed at psa_cipher_update with error code : %d", status); free(outbuf); return ESP_FAIL; } - ret = mbedtls_aes_crypt_ctr(&session->ctx_aes, PUBLIC_KEY_LEN, - &session->nc_off, session->rand, - session->stb, session->device_pubkey, outbuf); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_aes_crypt_ctr with error code : %d", ret); - free(outbuf); - return ESP_FAIL; - } + session->key_id = key_id; Sec1Payload *out = (Sec1Payload *) malloc(sizeof(Sec1Payload)); if (!out) { @@ -292,8 +285,8 @@ static esp_err_t verify_response1(session_t *session, SessionData *resp) uint8_t *cli_pubkey = session->client_pubkey; uint8_t *dev_pubkey = session->device_pubkey; - hexdump("Device pubkey", dev_pubkey, PUBLIC_KEY_LEN); - hexdump("Client pubkey", cli_pubkey, PUBLIC_KEY_LEN); + hexdump("Device pubkey1", dev_pubkey, PUBLIC_KEY_LEN); + hexdump("Client pubkey1", cli_pubkey, PUBLIC_KEY_LEN); if ((resp->proto_case != SESSION_DATA__PROTO_SEC1) || (resp->sec1->msg != SEC1_MSG_TYPE__Session_Response1)) { @@ -304,13 +297,17 @@ static esp_err_t verify_response1(session_t *session, SessionData *resp) uint8_t check_buf[PUBLIC_KEY_LEN]; Sec1Payload *in = (Sec1Payload *) resp->sec1; - int ret = mbedtls_aes_crypt_ctr(&session->ctx_aes, PUBLIC_KEY_LEN, - &session->nc_off, session->rand, session->stb, - in->sr1->device_verify_data.data, check_buf); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_aes_crypt_ctr with error code : %d", ret); + hexdump("Device verify data", in->sr1->device_verify_data.data, in->sr1->device_verify_data.len); + hexdump("Rand: ", session->rand, sizeof(session->rand)); + + + size_t out_len = 0; + psa_status_t status = psa_cipher_update(&session->ctx_aes, in->sr1->device_verify_data.data, in->sr1->device_verify_data.len, check_buf, sizeof(check_buf), &out_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed at psa_cipher_update with error code : %d", status); return ESP_FAIL; } + hexdump("Dec Device verifier", check_buf, sizeof(check_buf)); if (memcmp(check_buf, session->client_pubkey, sizeof(session->client_pubkey)) != 0) { @@ -318,6 +315,9 @@ static esp_err_t verify_response1(session_t *session, SessionData *resp) return ESP_FAIL; } + /* Initialize operation counter after successful handshake */ + session->op_counter = 0; + return ESP_OK; } @@ -358,6 +358,14 @@ static esp_err_t test_delete_session(session_t *session) if (test_sec->cleanup && (test_sec->cleanup(sec_inst) != ESP_OK)) { return ESP_FAIL; } + + psa_destroy_key(session->client_key_id); + session->client_key_id = 0; + + psa_destroy_key(session->key_id); + session->key_id = 0; + + psa_cipher_abort(&session->ctx_aes); return ESP_OK; } @@ -377,52 +385,43 @@ static esp_err_t test_sec_endpoint(session_t *session) ssize_t outlen = 0; uint8_t *outbuf = NULL; - mbedtls_ecdh_init(&session->ctx_client); - mbedtls_ecdh_setup(&session->ctx_client, MBEDTLS_ECP_DP_CURVE25519); - mbedtls_ctr_drbg_init(&session->ctr_drbg); + psa_status_t status; - mbedtls_entropy_init(&session->entropy); - ret = mbedtls_ctr_drbg_seed(&session->ctr_drbg, mbedtls_entropy_func, - &session->entropy, NULL, 0); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ctr_drbg_seed with error code : %d", ret); - goto abort_test_sec_endpoint; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + if (session->client_key_id != 0) { + psa_destroy_key(session->client_key_id); + session->client_key_id = 0; } - ret = mbedtls_ecp_group_load(ACCESS_ECDH(&session->ctx_client, grp), MBEDTLS_ECP_DP_CURVE25519); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ecp_group_load with error code : %d", ret); - goto abort_test_sec_endpoint; - } + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)); + psa_set_key_bits(&key_attributes, 255); + psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); - ret = mbedtls_ecdh_gen_public(ACCESS_ECDH(&session->ctx_client, grp), - ACCESS_ECDH(&session->ctx_client, d), - ACCESS_ECDH(&session->ctx_client, Q), - mbedtls_ctr_drbg_random, - &session->ctr_drbg); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_ecdh_gen_public with error code : %d", ret); - goto abort_test_sec_endpoint; + status = psa_generate_key(&key_attributes, &session->client_key_id); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_generate_key failed with status=%d", status); + psa_reset_key_attributes(&key_attributes); + return ESP_FAIL; } + psa_reset_key_attributes(&key_attributes); + size_t olen = 0; if (session->weak) { - /* Read zero client public key */ - ret = mbedtls_mpi_read_binary(ACCESS_ECDH(&session->ctx_client, Q).MBEDTLS_PRIVATE(X), - session->client_pubkey, - PUBLIC_KEY_LEN); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_read_binary with error code : %d", ret); - goto abort_test_sec_endpoint; + // If weak key is request, just set the session->client_pubkey to be 0 + memset(session->client_pubkey, 0, PUBLIC_KEY_LEN); + } else { + status = psa_export_public_key(session->client_key_id, session->client_pubkey, PUBLIC_KEY_LEN, &olen); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_export_public_key failed with status=%d", status); + psa_reset_key_attributes(&key_attributes); + return ESP_FAIL; } } - ret = mbedtls_mpi_write_binary(ACCESS_ECDH(&session->ctx_client, Q).MBEDTLS_PRIVATE(X), - session->client_pubkey, - PUBLIC_KEY_LEN); - if (ret != 0) { - ESP_LOGE(TAG, "Failed at mbedtls_mpi_write_binary with error code : %d", ret); - goto abort_test_sec_endpoint; - } - flip_endian(session->client_pubkey, PUBLIC_KEY_LEN); + + hexdump("Client public key", session->client_pubkey, PUBLIC_KEY_LEN); /*********** Transaction0 = SessionCmd0 + SessionResp0 ****************/ session_data__init(&req); @@ -511,17 +510,14 @@ static esp_err_t test_sec_endpoint(session_t *session) } session_data__free_unpacked(resp, NULL); - mbedtls_ecdh_free(&session->ctx_client); - mbedtls_ctr_drbg_free(&session->ctr_drbg); - mbedtls_entropy_free(&session->entropy); + psa_destroy_key(session->client_key_id); + session->client_key_id = 0; return ESP_OK; abort_test_sec_endpoint: - - mbedtls_ecdh_free(&session->ctx_client); - mbedtls_ctr_drbg_free(&session->ctr_drbg); - mbedtls_entropy_free(&session->entropy); + psa_destroy_key(session->client_key_id); + session->client_key_id = 0; return ESP_FAIL; } @@ -564,11 +560,17 @@ static esp_err_t test_req_endpoint(session_t *session) // Check if the AES key is correctly set before calling the software encryption // API. Without this check, the code will crash, resulting in a test case failure. // For hardware AES, portability layer takes care of this. - if (session->ctx_aes.MBEDTLS_PRIVATE(nr) > 0) { + // if (session->ctx_aes.MBEDTLS_PRIVATE(nr) > 0) { + if (session->ctx_aes.MBEDTLS_PRIVATE(id) > 0) { #endif - mbedtls_aes_crypt_ctr(&session->ctx_aes, sizeof(rand_test_data), &session->nc_off, - session->rand, session->stb, rand_test_data, enc_test_data); + size_t out_len = 0; + psa_status_t status = psa_cipher_update(&session->ctx_aes, rand_test_data, sizeof(rand_test_data), enc_test_data, sizeof(enc_test_data), &out_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error updating cipher, status: %d", status); + return ESP_FAIL; + } + #if !CONFIG_MBEDTLS_HARDWARE_AES } #endif @@ -597,8 +599,14 @@ static esp_err_t test_req_endpoint(session_t *session) memcpy(verify_data, enc_verify_data, verify_data_len); } else if (session->sec_ver == 1) { - mbedtls_aes_crypt_ctr(&session->ctx_aes, verify_data_len, &session->nc_off, - session->rand, session->stb, enc_verify_data, verify_data); + size_t out_len = 0; + psa_status_t status = psa_cipher_update(&session->ctx_aes, enc_verify_data, verify_data_len, verify_data, verify_data_len, &out_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "psa_cipher_update failed"); + free(verify_data); + free(enc_verify_data); + return ESP_FAIL; + } } free(enc_verify_data); @@ -715,7 +723,7 @@ static esp_err_t test_security1_no_encryption (void) return ESP_ERR_INVALID_STATE; } - // Intialise protocomm session with zero public keys + // Initialise protocomm session with zero public keys if (test_new_session(session) != ESP_OK) { ESP_LOGE(TAG, "Error creating new session"); stop_test_service(); @@ -794,7 +802,7 @@ static esp_err_t test_security1_session_overflow (void) return ESP_FAIL; } - // Intialise protocomm session with zero public keys + // Initialise protocomm session with zero public keys if (test_new_session(session1) != ESP_OK) { ESP_LOGE(TAG, "Error creating new session"); stop_test_service(); @@ -860,7 +868,7 @@ static esp_err_t test_security1_wrong_pop (void) return ESP_FAIL; } - // Intialise protocomm session with zero public keys + // Initialise protocomm session with zero public keys if (test_new_session(session) != ESP_OK) { ESP_LOGE(TAG, "Error creating new session"); stop_test_service(); @@ -975,7 +983,7 @@ static esp_err_t test_security1_weak_session (void) return ESP_FAIL; } - // Intialise protocomm session with zero public keys + // Initialise protocomm session with zero public keys if (test_new_session(session) != ESP_OK) { ESP_LOGE(TAG, "Error creating new session"); stop_test_service(); @@ -1028,7 +1036,7 @@ static esp_err_t test_protocomm (session_t *session) return ESP_FAIL; } - // Intialise protocomm session with zero public keys + // Initialise protocomm session with zero public keys if (test_new_session(session) != ESP_OK) { ESP_LOGE(TAG, "Error creating new session"); stop_test_service(); @@ -1136,7 +1144,6 @@ TEST_CASE("leak test", "[PROTOCOMM]") /* Run all tests passively. Any leaks due * to protocomm should show up now */ unsigned pre_start_mem = esp_get_free_heap_size(); - test_security0(); test_security1(); test_security1_no_encryption(); @@ -1190,8 +1197,3 @@ TEST_CASE("security 1 weak session test", "[PROTOCOMM]") { TEST_ASSERT(test_security1_weak_session() == ESP_OK); } - -void app_main(void) -{ - unity_run_menu(); -} diff --git a/components/protocomm/test_apps/main/test_srp.c b/components/protocomm/test_apps/main/test_srp.c new file mode 100644 index 00000000000..ccd5b46e46a --- /dev/null +++ b/components/protocomm/test_apps/main/test_srp.c @@ -0,0 +1,325 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include +#include "esp_srp.h" +#include "esp_log.h" +#include "test_utils.h" +#include "esp_rom_crc.h" + +static const char *TAG = "srp_test"; + +// Example username and password +static const char *username = "wifiprov"; +static const char *password = "abcd1234"; + +static const char sec2_salt[] = { + 0x03, 0x6e, 0xe0, 0xc7, 0xbc, 0xb9, 0xed, 0xa8, 0x4c, 0x9e, 0xac, 0x97, 0xd9, 0x3d, 0xec, 0xf4 +}; + +static const char sec2_verifier[] = { + 0x7c, 0x7c, 0x85, 0x47, 0x65, 0x08, 0x94, 0x6d, 0xd6, 0x36, 0xaf, 0x37, 0xd7, 0xe8, 0x91, 0x43, + 0x78, 0xcf, 0xfd, 0x61, 0x6c, 0x59, 0xd2, 0xf8, 0x39, 0x08, 0x12, 0x72, 0x38, 0xde, 0x9e, 0x24, + 0xa4, 0x70, 0x26, 0x1c, 0xdf, 0xa9, 0x03, 0xc2, 0xb2, 0x70, 0xe7, 0xb1, 0x32, 0x24, 0xda, 0x11, + 0x1d, 0x97, 0x18, 0xdc, 0x60, 0x72, 0x08, 0xcc, 0x9a, 0xc9, 0x0c, 0x48, 0x27, 0xe2, 0xae, 0x89, + 0xaa, 0x16, 0x25, 0xb8, 0x04, 0xd2, 0x1a, 0x9b, 0x3a, 0x8f, 0x37, 0xf6, 0xe4, 0x3a, 0x71, 0x2e, + 0xe1, 0x27, 0x86, 0x6e, 0xad, 0xce, 0x28, 0xff, 0x54, 0x46, 0x60, 0x1f, 0xb9, 0x96, 0x87, 0xdc, + 0x57, 0x40, 0xa7, 0xd4, 0x6c, 0xc9, 0x77, 0x54, 0xdc, 0x16, 0x82, 0xf0, 0xed, 0x35, 0x6a, 0xc4, + 0x70, 0xad, 0x3d, 0x90, 0xb5, 0x81, 0x94, 0x70, 0xd7, 0xbc, 0x65, 0xb2, 0xd5, 0x18, 0xe0, 0x2e, + 0xc3, 0xa5, 0xf9, 0x68, 0xdd, 0x64, 0x7b, 0xb8, 0xb7, 0x3c, 0x9c, 0xfc, 0x00, 0xd8, 0x71, 0x7e, + 0xb7, 0x9a, 0x7c, 0xb1, 0xb7, 0xc2, 0xc3, 0x18, 0x34, 0x29, 0x32, 0x43, 0x3e, 0x00, 0x99, 0xe9, + 0x82, 0x94, 0xe3, 0xd8, 0x2a, 0xb0, 0x96, 0x29, 0xb7, 0xdf, 0x0e, 0x5f, 0x08, 0x33, 0x40, 0x76, + 0x52, 0x91, 0x32, 0x00, 0x9f, 0x97, 0x2c, 0x89, 0x6c, 0x39, 0x1e, 0xc8, 0x28, 0x05, 0x44, 0x17, + 0x3f, 0x68, 0x02, 0x8a, 0x9f, 0x44, 0x61, 0xd1, 0xf5, 0xa1, 0x7e, 0x5a, 0x70, 0xd2, 0xc7, 0x23, + 0x81, 0xcb, 0x38, 0x68, 0xe4, 0x2c, 0x20, 0xbc, 0x40, 0x57, 0x76, 0x17, 0xbd, 0x08, 0xb8, 0x96, + 0xbc, 0x26, 0xeb, 0x32, 0x46, 0x69, 0x35, 0x05, 0x8c, 0x15, 0x70, 0xd9, 0x1b, 0xe9, 0xbe, 0xcc, + 0xa9, 0x38, 0xa6, 0x67, 0xf0, 0xad, 0x50, 0x13, 0x19, 0x72, 0x64, 0xbf, 0x52, 0xc2, 0x34, 0xe2, + 0x1b, 0x11, 0x79, 0x74, 0x72, 0xbd, 0x34, 0x5b, 0xb1, 0xe2, 0xfd, 0x66, 0x73, 0xfe, 0x71, 0x64, + 0x74, 0xd0, 0x4e, 0xbc, 0x51, 0x24, 0x19, 0x40, 0x87, 0x0e, 0x92, 0x40, 0xe6, 0x21, 0xe7, 0x2d, + 0x4e, 0x37, 0x76, 0x2f, 0x2e, 0xe2, 0x68, 0xc7, 0x89, 0xe8, 0x32, 0x13, 0x42, 0x06, 0x84, 0x84, + 0x53, 0x4a, 0xb3, 0x0c, 0x1b, 0x4c, 0x8d, 0x1c, 0x51, 0x97, 0x19, 0xab, 0xae, 0x77, 0xff, 0xdb, + 0xec, 0xf0, 0x10, 0x95, 0x34, 0x33, 0x6b, 0xcb, 0x3e, 0x84, 0x0f, 0xb9, 0xd8, 0x5f, 0xb8, 0xa0, + 0xb8, 0x55, 0x53, 0x3e, 0x70, 0xf7, 0x18, 0xf5, 0xce, 0x7b, 0x4e, 0xbf, 0x27, 0xce, 0xce, 0xa8, + 0xb3, 0xbe, 0x40, 0xc5, 0xc5, 0x32, 0x29, 0x3e, 0x71, 0x64, 0x9e, 0xde, 0x8c, 0xf6, 0x75, 0xa1, + 0xe6, 0xf6, 0x53, 0xc8, 0x31, 0xa8, 0x78, 0xde, 0x50, 0x40, 0xf7, 0x62, 0xde, 0x36, 0xb2, 0xba +}; + +static void test_srp_init_and_free(void) { + esp_srp_handle_t *handle = esp_srp_init(ESP_NG_3072); + TEST_ASSERT_NOT_NULL(handle); + esp_srp_free(handle); +} + +static void test_srp_gen_salt_verifier(void) { + char *bytes_salt = NULL; + char *verifier = NULL; + int verifier_len = 0; + esp_err_t err = esp_srp_gen_salt_verifier(username, strlen(username), + password, strlen(password), + &bytes_salt, 16, &verifier, &verifier_len); + TEST_ASSERT_EQUAL(ESP_OK, err); + TEST_ASSERT_NOT_NULL(bytes_salt); + TEST_ASSERT_NOT_NULL(verifier); + + // Verify salt length is as requested + TEST_ASSERT_EQUAL(16, 16); + + // Verify verifier length is correct for 3072-bit SRP + TEST_ASSERT_GREATER_THAN(0, verifier_len); + + // Log the generated salt and verifier for debugging + ESP_LOG_BUFFER_HEXDUMP("Generated Salt", bytes_salt, 16, ESP_LOG_INFO); + ESP_LOG_BUFFER_HEXDUMP("Generated Verifier", verifier, verifier_len, ESP_LOG_INFO); + + free(bytes_salt); + free(verifier); +} + +static void test_srp_set_salt_verifier(void) { + esp_srp_handle_t *handle = esp_srp_init(ESP_NG_3072); + TEST_ASSERT_NOT_NULL(handle); + + esp_err_t err = esp_srp_set_salt_verifier(handle, sec2_salt, sizeof(sec2_salt), + sec2_verifier, sizeof(sec2_verifier)); + TEST_ASSERT_EQUAL(ESP_OK, err); + + char *bytes_B = NULL; + int len_B = 0; + err = esp_srp_srv_pubkey_from_salt_verifier(handle, &bytes_B, &len_B); + TEST_ASSERT_EQUAL(ESP_OK, err); + // Verify B length is correct for 3072-bit SRP (384 bytes) + TEST_ASSERT_EQUAL(384, len_B); + + esp_srp_free(handle); +} + +static void test_srp_srv_pubkey(void) { + esp_srp_handle_t *handle = esp_srp_init(ESP_NG_3072); + TEST_ASSERT_NOT_NULL(handle); + + char *bytes_B = NULL; + int len_B = 0; + char *bytes_salt = NULL; + esp_err_t err = esp_srp_srv_pubkey(handle, username, strlen(username), + password, strlen(password), 16, + &bytes_B, &len_B, &bytes_salt); + TEST_ASSERT_EQUAL(ESP_OK, err); + TEST_ASSERT_NOT_NULL(bytes_B); + TEST_ASSERT_NOT_NULL(bytes_salt); + + // Verify salt and B length + TEST_ASSERT_EQUAL(16, 16); + TEST_ASSERT_EQUAL(384, len_B); + + // Log for debugging + ESP_LOG_BUFFER_HEXDUMP("Generated Salt", bytes_salt, 16, ESP_LOG_INFO); + ESP_LOG_BUFFER_HEXDUMP("Generated Server Public Key B", bytes_B, len_B, ESP_LOG_INFO); + + esp_srp_free(handle); +} + +static void test_srp_get_session_key(void) { + esp_srp_handle_t *handle = esp_srp_init(ESP_NG_3072); + TEST_ASSERT_NOT_NULL(handle); + + char *bytes_B = NULL; + int len_B = 0; + char *bytes_salt = NULL; + esp_err_t err = esp_srp_srv_pubkey(handle, username, strlen(username), + password, strlen(password), 16, + &bytes_B, &len_B, &bytes_salt); + TEST_ASSERT_EQUAL(ESP_OK, err); + + // In a real scenario, bytes_A would be from client + // For testing purposes, we use bytes_B as a convenient value (server talks to itself) + char *bytes_key = NULL; + uint16_t len_key = 0; + err = esp_srp_get_session_key(handle, bytes_B, len_B, &bytes_key, &len_key); + TEST_ASSERT_EQUAL(ESP_OK, err); + TEST_ASSERT_NOT_NULL(bytes_key); + + // Verify session key length (SHA512 hash) + TEST_ASSERT_EQUAL(64, len_key); + + // Log session key for debugging + ESP_LOG_BUFFER_HEXDUMP("Session Key", bytes_key, len_key, ESP_LOG_INFO); + + esp_srp_free(handle); +} + +static void test_srp_exchange_proofs(void) { + esp_srp_handle_t *handle = esp_srp_init(ESP_NG_3072); + TEST_ASSERT_NOT_NULL(handle); + + char *bytes_B = NULL; + int len_B = 0; + char *bytes_salt = NULL; + esp_err_t err = esp_srp_srv_pubkey(handle, username, strlen(username), + password, strlen(password), 16, + &bytes_B, &len_B, &bytes_salt); + TEST_ASSERT_EQUAL(ESP_OK, err); + + char *bytes_key = NULL; + uint16_t len_key = 0; + err = esp_srp_get_session_key(handle, bytes_B, len_B, &bytes_key, &len_key); + TEST_ASSERT_EQUAL(ESP_OK, err); + + // In a real environment, bytes_user_proof would be calculated by the client + // For our test, we'll generate zeros - this simulates an authentication failure scenario + char bytes_user_proof[64] = {0}; // Example proof + char bytes_host_proof[64] = {0}; + + // This should fail since user proof is zeros and doesn't match expected value + err = esp_srp_exchange_proofs(handle, (char *)username, strlen(username), + bytes_user_proof, bytes_host_proof); + TEST_ASSERT_EQUAL(ESP_FAIL, err); + + esp_srp_free(handle); +} + +// Add test for error handling with invalid parameters +static void test_srp_error_handling(void) { + esp_srp_handle_t *handle = esp_srp_init(ESP_NG_3072); + TEST_ASSERT_NOT_NULL(handle); + + // Test with NULL salt + esp_err_t err = esp_srp_set_salt_verifier(handle, NULL, sizeof(sec2_salt), + sec2_verifier, sizeof(sec2_verifier)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, err); + + // Test with zero salt length + err = esp_srp_set_salt_verifier(handle, sec2_salt, 0, + sec2_verifier, sizeof(sec2_verifier)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, err); + + // Test with NULL verifier + err = esp_srp_set_salt_verifier(handle, sec2_salt, sizeof(sec2_salt), + NULL, sizeof(sec2_verifier)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, err); + + // Test with zero verifier length + err = esp_srp_set_salt_verifier(handle, sec2_salt, sizeof(sec2_salt), + sec2_verifier, 0); + TEST_ASSERT_NOT_EQUAL(ESP_OK, err); + + esp_srp_free(handle); +} + +// Test verifier calculation consistency +static void test_srp_verifier_consistency(void) { + char *bytes_salt1 = NULL; + char *verifier1 = NULL; + int verifier_len1 = 0; + + // Generate first salt/verifier pair + esp_err_t err = esp_srp_gen_salt_verifier(username, strlen(username), + password, strlen(password), + &bytes_salt1, 16, &verifier1, &verifier_len1); + TEST_ASSERT_EQUAL(ESP_OK, err); + + // Generate second salt/verifier pair + char *bytes_salt2 = NULL; + char *verifier2 = NULL; + int verifier_len2 = 0; + err = esp_srp_gen_salt_verifier(username, strlen(username), + password, strlen(password), + &bytes_salt2, 16, &verifier2, &verifier_len2); + TEST_ASSERT_EQUAL(ESP_OK, err); + + // Salts should be different (randomly generated) + TEST_ASSERT_NOT_EQUAL(0, memcmp(bytes_salt1, bytes_salt2, 16)); + + // Verifiers should also be different since they depend on the salt + TEST_ASSERT_NOT_EQUAL(0, memcmp(verifier1, verifier2, verifier_len1)); + + free(bytes_salt1); + free(verifier1); + free(bytes_salt2); + free(verifier2); +} + +static void test_srp_pubkey_randomness(void) { + esp_srp_handle_t *handle = esp_srp_init(ESP_NG_3072); + TEST_ASSERT_NOT_NULL(handle); + + esp_err_t err = esp_srp_set_salt_verifier(handle, sec2_salt, sizeof(sec2_salt), + sec2_verifier, sizeof(sec2_verifier)); + TEST_ASSERT_EQUAL(ESP_OK, err); + + // Generate first public key + char *bytes_B1 = NULL; + int len_B1 = 0; + err = esp_srp_srv_pubkey_from_salt_verifier(handle, &bytes_B1, &len_B1); + TEST_ASSERT_EQUAL(ESP_OK, err); + TEST_ASSERT_NOT_NULL(bytes_B1); + TEST_ASSERT_EQUAL(384, len_B1); + + // Generate second public key with same salt/verifier + char *bytes_B2 = NULL; + int len_B2 = 0; + err = esp_srp_srv_pubkey_from_salt_verifier(handle, &bytes_B2, &len_B2); + TEST_ASSERT_EQUAL(ESP_OK, err); + TEST_ASSERT_NOT_NULL(bytes_B2); + TEST_ASSERT_EQUAL(384, len_B2); + + // Keys should be different due to random b generation + TEST_ASSERT_NOT_EQUAL(0, memcmp(bytes_B1, bytes_B2, len_B1)); + + // Calculate CRCs for logging + uint32_t crc1 = esp_rom_crc32_le(0, (uint8_t*)bytes_B1, len_B1); + uint32_t crc2 = esp_rom_crc32_le(0, (uint8_t*)bytes_B2, len_B2); + ESP_LOGI(TAG, "Public key CRCs: %u, %u (should be different)", crc1, crc2); + + free(bytes_B1); + bytes_B1 = NULL; + esp_srp_free(handle); +} + +TEST_CASE("SRP init and free test", "[SRP]") +{ + test_srp_init_and_free(); +} + +TEST_CASE("SRP generate salt and verifier test", "[SRP]") +{ + test_srp_gen_salt_verifier(); +} + +TEST_CASE("SRP set salt and verifier test", "[SRP]") +{ + test_srp_set_salt_verifier(); +} + +TEST_CASE("SRP server public key test", "[SRP]") +{ + test_srp_srv_pubkey(); +} + +TEST_CASE("SRP get session key test", "[SRP]") +{ + test_srp_get_session_key(); +} + +TEST_CASE("SRP exchange proofs test", "[SRP]") +{ + test_srp_exchange_proofs(); +} + +TEST_CASE("SRP error handling test", "[SRP]") +{ + test_srp_error_handling(); +} + +TEST_CASE("SRP verifier consistency test", "[SRP]") +{ + test_srp_verifier_consistency(); +} + +TEST_CASE("SRP public key randomness test", "[SRP]") +{ + test_srp_pubkey_randomness(); +} diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c index 6328136a911..751b59149d1 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ - +#define MBEDTLS_ALLOW_PRIVATE_ACCESS #ifdef ESP_PLATFORM #include "esp_system.h" #include "mbedtls/bignum.h" @@ -16,6 +16,7 @@ #include "random.h" #include "sha256.h" #include "mbedtls/pk.h" +#include "mbedtls/psa_util.h" struct crypto_bignum *crypto_bignum_init(void) { @@ -37,10 +38,12 @@ struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len) return NULL; } + mbedtls_mpi_init(bn); MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(bn, buf, len)); return (struct crypto_bignum *) bn; cleanup: + mbedtls_mpi_free(bn); os_free(bn); return NULL; } @@ -216,7 +219,7 @@ int crypto_bignum_is_odd(const struct crypto_bignum *a) int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) { return ((mbedtls_mpi_random((mbedtls_mpi *) r, 0, (const mbedtls_mpi *) m, - mbedtls_esp_random, NULL) != 0) ? -1 : 0); + mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE) != 0) ? -1 : 0); } int crypto_bignum_legendre(const struct crypto_bignum *a, diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c index b7c9fab6972..271654c8a35 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define MBEDTLS_ALLOW_PRIVATE_ACCESS + #ifdef ESP_PLATFORM #include "esp_system.h" #include "mbedtls/bignum.h" @@ -17,13 +19,14 @@ #include "random.h" #include "mbedtls/ecp.h" - #include "mbedtls/pk.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/sha256.h" #include "mbedtls/asn1write.h" #include "mbedtls/error.h" #include "mbedtls/oid.h" +#include +#include "psa/crypto.h" +#include "psa/crypto_sizes.h" +#include "esp_heap_caps.h" #define ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) #define ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) @@ -34,8 +37,24 @@ #define ACCESS_ECDH(S, var) S->MBEDTLS_PRIVATE(ctx).MBEDTLS_PRIVATE(mbed_ecdh).MBEDTLS_PRIVATE(var) #endif +#define ESP_SUP_MAX_ECC_KEY_SIZE 256 + #ifdef CONFIG_ECC +// Wrapper structure for EC keys that includes PSA key ID, curve info, and group +// This allows us to avoid memory leaks by storing everything with the key +typedef struct { + psa_key_id_t key_id; + mbedtls_ecp_group_id curve_id; + mbedtls_ecp_group group; + mbedtls_ecp_point *cached_public_key; + mbedtls_mpi *cached_private_key; +} crypto_ec_key_wrapper_t; + +// Helper macro to get key_id from wrapper +#define GET_KEY_ID(key) (((crypto_ec_key_wrapper_t *)(key))->key_id) + +// NOTE: Used with mpi, no PSA equivalent struct crypto_ec *crypto_ec_init(int group) { mbedtls_ecp_group *e; @@ -80,6 +99,7 @@ void crypto_ec_deinit(struct crypto_ec *e) os_free(e); } +// NOTE: Used with mpi, no PSA equivalent struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e) { mbedtls_ecp_point *pt; @@ -293,9 +313,8 @@ int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, (mbedtls_ecp_point *) res, (const mbedtls_mpi *)b, (const mbedtls_ecp_point *)p, - mbedtls_esp_random, - NULL)); - + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE)); cleanup: return ret ? -1 : 0; } @@ -476,10 +495,33 @@ int crypto_ec_point_cmp(const struct crypto_ec *e, int crypto_ec_key_compare(struct crypto_ec_key *key1, struct crypto_ec_key *key2) { - if (mbedtls_pk_check_pair((mbedtls_pk_context *)key1, (mbedtls_pk_context *)key2, mbedtls_esp_random, NULL) < 0) { + crypto_ec_key_wrapper_t *wrapper1 = (crypto_ec_key_wrapper_t *)key1; + crypto_ec_key_wrapper_t *wrapper2 = (crypto_ec_key_wrapper_t *)key2; + if (!wrapper1 || !wrapper2) { return 0; } - return 1; + + unsigned char pub1[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(ESP_SUP_MAX_ECC_KEY_SIZE)]; + unsigned char pub2[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(ESP_SUP_MAX_ECC_KEY_SIZE)]; + + size_t key1_len, key2_len; + + psa_status_t status = psa_export_public_key(wrapper1->key_id, pub1, sizeof(pub1), &key1_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "crypto_ec_key_compare: psa_export_public_key failed with %d", status); + return 0; + } + status = psa_export_public_key(wrapper2->key_id, pub2, sizeof(pub2), &key2_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "crypto_ec_key_compare: psa_export_public_key failed with %d", status); + return 0; + } + + if ((key1_len == key2_len) && (os_memcmp(pub1, pub2, key1_len) == 0)) { + return 1; + } + + return 0; } void crypto_debug_print_point(const char *title, struct crypto_ec *e, @@ -496,104 +538,354 @@ void crypto_debug_print_point(const char *title, struct crypto_ec *e, wpa_hexdump(MSG_ERROR, "y:", y, 32); } -static struct crypto_ec_key *crypto_alloc_key(void) +// Helper to initialize group in wrapper +static int init_group_in_wrapper(crypto_ec_key_wrapper_t *wrapper) { - mbedtls_pk_context *key = os_malloc(sizeof(*key)); - - if (!key) { - wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); - return NULL; + if (!wrapper || wrapper->curve_id == MBEDTLS_ECP_DP_NONE) { + return -1; } - mbedtls_pk_init(key); - return (struct crypto_ec_key *)key; + mbedtls_ecp_group_init(&wrapper->group); + if (mbedtls_ecp_group_load(&wrapper->group, wrapper->curve_id) != 0) { + mbedtls_ecp_group_free(&wrapper->group); + return -1; + } + + return 0; +} + +static psa_ecc_family_t group_id_to_psa(mbedtls_ecp_group_id grp_id, size_t *bits) +{ + switch (grp_id) { + case MBEDTLS_ECP_DP_SECP192R1: + if (bits) { + *bits = 192; + } + return PSA_ECC_FAMILY_SECP_R1; + case MBEDTLS_ECP_DP_SECP256R1: + if (bits) { + *bits = 256; + } + return PSA_ECC_FAMILY_SECP_R1; + case MBEDTLS_ECP_DP_SECP384R1: + if (bits) { + *bits = 384; + } + return PSA_ECC_FAMILY_SECP_R1; + case MBEDTLS_ECP_DP_SECP521R1: + if (bits) { + *bits = 521; + } + return PSA_ECC_FAMILY_SECP_R1; + case MBEDTLS_ECP_DP_BP256R1: + if (bits) { + *bits = 256; + } + return PSA_ECC_FAMILY_BRAINPOOL_P_R1; + case MBEDTLS_ECP_DP_BP384R1: + if (bits) { + *bits = 384; + } + return PSA_ECC_FAMILY_BRAINPOOL_P_R1; + case MBEDTLS_ECP_DP_BP512R1: + if (bits) { + *bits = 512; + } + return PSA_ECC_FAMILY_BRAINPOOL_P_R1; + case MBEDTLS_ECP_DP_CURVE25519: + if (bits) { + *bits = 255; + } + return PSA_ECC_FAMILY_MONTGOMERY; + case MBEDTLS_ECP_DP_SECP192K1: + if (bits) { + *bits = 192; + } + return PSA_ECC_FAMILY_SECP_K1; + // case MBEDTLS_ECP_DP_SECP224K1: + // if (bits) { + // *bits = 224; + // } + // return PSA_ECC_FAMILY_SECP_K1; + case MBEDTLS_ECP_DP_SECP256K1: + if (bits) { + *bits = 256; + } + return PSA_ECC_FAMILY_SECP_K1; + case MBEDTLS_ECP_DP_CURVE448: + if (bits) { + *bits = 448; + } + return PSA_ECC_FAMILY_MONTGOMERY; + default: + if (bits) { + *bits = 0; + } + return 0; + } } struct crypto_ec_key * crypto_ec_key_set_pub(const struct crypto_ec_group *group, const u8 *buf, size_t len) { - mbedtls_ecp_point *point = NULL; - struct crypto_ec_key *pkey = NULL; - int ret; - mbedtls_pk_context *key = (mbedtls_pk_context *)crypto_alloc_key(); - mbedtls_ecp_group *ecp_grp = (mbedtls_ecp_group *)group; - - if (!key) { - wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); + mbedtls_ecp_group *grp = (mbedtls_ecp_group *)group; + if (!grp || grp->id == MBEDTLS_ECP_DP_NONE) { + wpa_printf(MSG_ERROR, "Invalid ECC group"); return NULL; } - point = (mbedtls_ecp_point *)crypto_ec_point_from_bin((struct crypto_ec *)group, buf); - if (!point) { - wpa_printf(MSG_ERROR, "%s: Point initialization failed", __func__); - goto fail; - } - if (crypto_ec_point_is_at_infinity((struct crypto_ec *)group, (struct crypto_ec_point *)point)) { - wpa_printf(MSG_ERROR, "Point is at infinity"); - goto fail; - } - if (!crypto_ec_point_is_on_curve((struct crypto_ec *)group, (struct crypto_ec_point *)point)) { - wpa_printf(MSG_ERROR, "Point not on curve"); - goto fail; + // Convert mbedtls group ID to PSA curve family + size_t bits = 0; + psa_ecc_family_t ecc_family = group_id_to_psa(grp->id, &bits); + if (ecc_family == 0) { + wpa_printf(MSG_ERROR, "Unsupported curve group"); + return NULL; } - if (mbedtls_ecp_check_pubkey(ecp_grp, point) < 0) { - // ideally should have failed in upper condition, duplicate code?? - wpa_printf(MSG_ERROR, "Invalid key"); - goto fail; + // Create wrapper structure with key ID and curve info + crypto_ec_key_wrapper_t *wrapper = os_calloc(1, sizeof(crypto_ec_key_wrapper_t)); + if (!wrapper) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + return NULL; } - /* Assign values */ - if ((ret = mbedtls_pk_setup(key, - mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY))) != 0) { - goto fail; + wrapper->curve_id = grp->id; // Store curve ID for later use + mbedtls_ecp_group_init(&wrapper->group); // Initialize group structure + wrapper->group.id = MBEDTLS_ECP_DP_NONE; // Mark as not loaded yet (lazy init) + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + u8* key_buf = NULL; + size_t key_len = 0; + size_t key_bits = 0; + + if (ecc_family != PSA_ECC_FAMILY_MONTGOMERY) { + /* + * For non-Montgomery curves, the public key is represented as an + * uncompressed point (0x04 || X || Y). + * DPP protocol sends raw X||Y (even length, no prefix). + * Also supports compressed format (0x02/0x03 || X) and + * uncompressed format (0x04 || X || Y). + */ + + // Check if buffer has a format prefix (0x04, 0x02, or 0x03) + if (len > 0 && (buf[0] == 0x04 || buf[0] == 0x02 || buf[0] == 0x03)) { + // Already has format prefix (0x04, 0x02, or 0x03) + key_buf = os_calloc(1, len); + if (!key_buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + os_free(wrapper); + return NULL; + } + + os_memcpy(key_buf, buf, len); + key_len = len; + // For uncompressed: key_bits = (len - 1) * 4 + // For compressed: key_bits = (len - 1) * 8 + if (buf[0] == 0x04) { + key_bits = (len - 1) * 4; + } else { + key_bits = (len - 1) * 8; + } + } else if ((len & 1) == 0) { + // Raw X||Y format (even length, no prefix) - prepend 0x04 + key_buf = os_calloc(1, len + 1); + if (!key_buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + os_free(wrapper); + return NULL; + } + + key_buf[0] = 0x04; + os_memcpy(key_buf + 1, buf, len); + key_len = len + 1; + // key_bits = len * 4 (since len = 2 * coordinate_size) + key_bits = len * 4; + } else { + // Odd length without format prefix - invalid format + wpa_printf(MSG_ERROR, "Invalid public key format: odd length without prefix"); + os_free(wrapper); + return NULL; + } + } else { + // Montgomery curves + key_buf = os_calloc(1, len); + if (!key_buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + os_free(wrapper); + return NULL; + } + os_memcpy(key_buf, buf, len); + key_len = len; + key_bits = len * 8; } - mbedtls_ecp_copy(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(Q), point); - mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(grp), ecp_grp->id); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_family)); + psa_set_key_bits(&key_attributes, key_bits); - pkey = (struct crypto_ec_key *)key; - crypto_ec_point_deinit((struct crypto_ec_point *)point, 0); - return pkey; -fail: - if (point) { - crypto_ec_point_deinit((struct crypto_ec_point *)point, 0); + psa_status_t status = psa_import_key(&key_attributes, key_buf, key_len, &wrapper->key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to import key, %d", status); + os_free(key_buf); + os_free(wrapper); + return NULL; } - if (key) { - mbedtls_pk_free(key); - } - pkey = NULL; - return pkey; + + os_free(key_buf); + + return (struct crypto_ec_key *)wrapper; } +/** + * crypto_ec_key_get_public_key - Get public key point from PSA key + * @key: Pointer to crypto_ec_key (PSA key ID) + * Returns: Pointer to mbedtls_ecp_point on success, NULL on failure + * + * Exports the public key directly from PSA and constructs an mbedtls_ecp_point. + * The exported format is uncompressed point: 0x04 || X || Y + */ struct crypto_ec_point *crypto_ec_key_get_public_key(struct crypto_ec_key *key) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { + return NULL; + } - return (struct crypto_ec_point *)&mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(Q); + // Return cached public key if already computed + if (wrapper->cached_public_key) { + return (struct crypto_ec_point *)wrapper->cached_public_key; + } + + psa_status_t status; + + // Export public key in uncompressed format: 0x04 || X || Y + uint8_t pub_key_buf[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(ESP_SUP_MAX_ECC_KEY_SIZE)]; + size_t pub_key_len = 0; + + status = psa_export_public_key(wrapper->key_id, pub_key_buf, sizeof(pub_key_buf), &pub_key_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to export public key: %d", status); + return NULL; + } + + // Validate format: should be 0x04 (uncompressed) || X || Y + if (pub_key_len < 3 || pub_key_buf[0] != 0x04) { + wpa_printf(MSG_ERROR, "Invalid public key format (expected uncompressed point)"); + return NULL; + } + + if ((pub_key_len - 1) % 2 != 0) { + wpa_printf(MSG_ERROR, "Invalid public key format: odd length"); + return NULL; + } + + // Calculate coordinate size: (total_len - 1) / 2 + size_t coord_size = (pub_key_len - 1) / 2; + + // Allocate and initialize the ECC point (cache it in wrapper) + mbedtls_ecp_point *point = os_calloc(1, sizeof(mbedtls_ecp_point)); + if (!point) { + wpa_printf(MSG_ERROR, "Failed to allocate ECC point"); + return NULL; + } + mbedtls_ecp_point_init(point); + + // Parse X coordinate + int ret = mbedtls_mpi_read_binary(&point->MBEDTLS_PRIVATE(X), + pub_key_buf + 1, coord_size); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to parse X coordinate: -0x%04x", -ret); + mbedtls_ecp_point_free(point); + os_free(point); + return NULL; + } + + // Parse Y coordinate + ret = mbedtls_mpi_read_binary(&point->MBEDTLS_PRIVATE(Y), + pub_key_buf + 1 + coord_size, coord_size); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to parse Y coordinate: -0x%04x", -ret); + mbedtls_ecp_point_free(point); + os_free(point); + return NULL; + } + + // Set Z coordinate to 1 (affine coordinates) + ret = mbedtls_mpi_lset(&point->MBEDTLS_PRIVATE(Z), 1); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to set Z coordinate: -0x%04x", -ret); + mbedtls_ecp_point_free(point); + os_free(point); + return NULL; + } + + // Cache the point in wrapper for later cleanup + wrapper->cached_public_key = point; + + return (struct crypto_ec_point *)point; } +/** + * crypto_ec_get_priv_key_der - Export private key in DER format + * @key: Pointer to crypto_ec_key (PSA key ID) + * @key_data: Output buffer for DER-encoded private key (caller must free) + * @key_len: Length of the DER-encoded key + * Returns: 0 on success, -1 on failure + * + * Note: Uses mbedtls temporarily for DER encoding as PSA lacks DER export API + */ int crypto_ec_get_priv_key_der(struct crypto_ec_key *key, unsigned char **key_data, int *key_len) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + if (!key || !key_data || !key_len) { + wpa_printf(MSG_ERROR, "Invalid parameters for DER export"); + return -1; + } + + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { + wpa_printf(MSG_ERROR, "Invalid key parameter for DER export"); + return -1; + } + + // Use mbedtls temporarily for DER encoding (PSA has no DER export) + mbedtls_pk_context pk_ctx; + mbedtls_pk_init(&pk_ctx); + + int ret = mbedtls_pk_copy_from_psa(wrapper->key_id, &pk_ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy key from PSA: -0x%04x", -ret); + mbedtls_pk_free(&pk_ctx); + return -1; + } + + // Allocate buffer for DER encoding char *der_data = os_malloc(ECP_PRV_DER_MAX_BYTES); - if (!der_data) { - wpa_printf(MSG_ERROR, "memory allocation failed"); + wpa_printf(MSG_ERROR, "Memory allocation failed for DER buffer"); + mbedtls_pk_free(&pk_ctx); return -1; } - *key_len = mbedtls_pk_write_key_der(pkey, (unsigned char *)der_data, ECP_PRV_DER_MAX_BYTES); - if (*key_len <= 0) { - wpa_printf(MSG_ERROR, "Failed to write priv key"); - os_free(der_data); - return -1; - } - *key_data = os_malloc(*key_len); - if (!*key_data) { - wpa_printf(MSG_ERROR, "memory allocation failed"); + // Write private key to DER format + *key_len = mbedtls_pk_write_key_der(&pk_ctx, (unsigned char *)der_data, ECP_PRV_DER_MAX_BYTES); + mbedtls_pk_free(&pk_ctx); + + if (*key_len <= 0) { + wpa_printf(MSG_ERROR, "Failed to write private key to DER: -0x%04x", -*key_len); os_free(der_data); return -1; } + + // Allocate output buffer + *key_data = os_malloc(*key_len); + if (!*key_data) { + wpa_printf(MSG_ERROR, "Memory allocation failed for output buffer"); + os_free(der_data); + return -1; + } + + // Copy DER data (mbedtls writes from end of buffer) os_memcpy(*key_data, der_data + ECP_PRV_DER_MAX_BYTES - *key_len, *key_len); os_free(der_data); @@ -602,62 +894,201 @@ int crypto_ec_get_priv_key_der(struct crypto_ec_key *key, unsigned char **key_da struct crypto_ec_group *crypto_ec_get_group_from_key(struct crypto_ec_key *key) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper || wrapper->curve_id == MBEDTLS_ECP_DP_NONE) { + return NULL; + } - return (struct crypto_ec_group *) & (mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp)); + // Group is stored directly in the wrapper, initialize if not already done + if (wrapper->group.id == MBEDTLS_ECP_DP_NONE) { + if (init_group_in_wrapper(wrapper) != 0) { + wpa_printf(MSG_ERROR, "crypto_ec_get_group_from_key: Failed to initialize group for curve %d", wrapper->curve_id); + return NULL; + } + } + + return (struct crypto_ec_group *)&wrapper->group; } int crypto_ec_key_group(struct crypto_ec_key *key) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { + return -1; + } - int iana_group = (int)crypto_ec_get_mbedtls_to_nist_group_id(mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(grp).id); + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status_t status = psa_get_key_attributes(wrapper->key_id, &key_attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "crypto_ec_key_group: psa_get_key_attributes failed: %d", status); + psa_reset_key_attributes(&key_attributes); + return -1; + } + + psa_key_type_t key_type = psa_get_key_type(&key_attributes); + psa_ecc_family_t ecc_family = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type); + int key_bits = psa_get_key_bits(&key_attributes); + psa_reset_key_attributes(&key_attributes); + + int iana_group = (int)crypto_ec_get_mbedtls_to_nist_group_id(ecc_family, key_bits); return iana_group; } struct crypto_bignum *crypto_ec_key_get_private_key(struct crypto_ec_key *key) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { + return NULL; + } - return ((struct crypto_bignum *) & (mbedtls_pk_ec(*pkey)->MBEDTLS_PRIVATE(d))); + // Return cached private key if already computed + if (wrapper->cached_private_key) { + return (struct crypto_bignum *)wrapper->cached_private_key; + } + + mbedtls_pk_context *pkey_ctx = os_calloc(1, sizeof(mbedtls_pk_context)); + if (!pkey_ctx) { + return NULL; + } + + mbedtls_pk_init(pkey_ctx); + + int ret = mbedtls_pk_copy_from_psa(wrapper->key_id, pkey_ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy key from PSA"); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_mpi *d = os_calloc(1, sizeof(mbedtls_mpi)); + if (!d) { + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_mpi_init(d); + + // Access the EC keypair directly from the PK context + // pkey_ctx->pk_ctx points to the underlying EC keypair + mbedtls_ecp_keypair *ec_key = (mbedtls_ecp_keypair *)(pkey_ctx->MBEDTLS_PRIVATE(pk_ctx)); + if (!ec_key) { + wpa_printf(MSG_ERROR, "Failed to get EC keypair from PK context"); + mbedtls_mpi_free(d); + os_free(d); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return NULL; + } + + ret = mbedtls_mpi_copy(d, &ec_key->MBEDTLS_PRIVATE(d)); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy private key"); + mbedtls_mpi_free(d); + os_free(d); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return NULL; + } + + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + + // Cache the private key in wrapper for later cleanup + wrapper->cached_private_key = d; + + return (struct crypto_bignum *)d; } int crypto_ec_get_publickey_buf(struct crypto_ec_key *key, u8 *key_buf, int len) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE + 10]; /* tag, length + MPI */ - unsigned char *c = buf + sizeof(buf); - int pk_len = 0; - - memset(buf, 0, sizeof(buf)); - pk_len = mbedtls_pk_write_pubkey(&c, buf, pkey); - - if (pk_len < 0) { + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { return -1; } - if (len == 0) { - return pk_len; + if (key_buf == NULL && len != 0) { + return -1; } - os_memcpy(key_buf, buf + MBEDTLS_MPI_MAX_SIZE + 10 - pk_len, pk_len); + psa_status_t status = PSA_SUCCESS; - return pk_len; + if (key_buf == NULL) { + // This is a call to determine the buffer length + // needed for the public key + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + status = psa_get_key_attributes(wrapper->key_id, &key_attributes); + if (status != PSA_SUCCESS) { + printf("psa_get_key_attributes failed with %d\n", status); + return -1; + } + + size_t key_bits = psa_get_key_bits(&key_attributes); + if (key_bits == 0) { + printf("psa_get_key_bits failed with %d\n", -1); + return -1; + } + + psa_key_type_t key_type = psa_get_key_type(&key_attributes); + + psa_reset_key_attributes(&key_attributes); + return PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits); + } + + size_t key_len = 0; + status = psa_export_public_key(wrapper->key_id, key_buf, len, &key_len); + if (status != PSA_SUCCESS) { + printf("psa_export_public_key failed with %d\n", status); + return -1; + } + + return key_len; } int crypto_write_pubkey_der(struct crypto_ec_key *key, unsigned char **key_buf) { unsigned char *buf = os_malloc(ECP_PUB_DER_MAX_BYTES); - if (!buf) { wpa_printf(MSG_ERROR, "memory allocation failed"); return -1; } - int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, buf, ECP_PUB_DER_MAX_BYTES); - if (len <= 0) { + + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { os_free(buf); return -1; } + mbedtls_pk_context *pkey_ctx = os_calloc(1, sizeof(mbedtls_pk_context)); + if (!pkey_ctx) { + os_free(buf); + return -1; + } + + mbedtls_pk_init(pkey_ctx); + + int ret = mbedtls_pk_copy_from_psa(wrapper->key_id, pkey_ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy key from PSA. ret: %d", ret); + os_free(buf); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return -1; + } + + int len = mbedtls_pk_write_pubkey_der(pkey_ctx, buf, ECP_PUB_DER_MAX_BYTES); + if (len <= 0) { + os_free(buf); + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); + return -1; + } + + mbedtls_pk_free(pkey_ctx); + os_free(pkey_ctx); *key_buf = os_malloc(len); if (!*key_buf) { @@ -670,144 +1101,221 @@ int crypto_write_pubkey_der(struct crypto_ec_key *key, unsigned char **key_buf) return len; } +/** + * crypto_ec_key_parse_priv - Parse private key and import to PSA + * @privkey: DER-encoded private key data + * @privkey_len: Length of private key data + * Returns: Pointer to crypto_ec_key (PSA key ID) or NULL on failure + * + * Note: Uses mbedtls for DER parsing (PSA needs metadata), returns PSA key + */ struct crypto_ec_key *crypto_ec_key_parse_priv(const u8 *privkey, size_t privkey_len) { - int ret; - mbedtls_pk_context *kctx = (mbedtls_pk_context *)crypto_alloc_key(); + /* + * As of PSA API v1.0, there is no way to import a private key with PSA APIs without + * knowing the metadata (such as type, size, etc.) of the key. So, we need to use + * mbedtls_pk_parse_key() to parse the private key and then import it into PSA. + */ - if (!kctx) { - wpa_printf(MSG_ERROR, "memory allocation failed"); + int ret; + mbedtls_pk_context kctx_storage; + mbedtls_pk_context *kctx = &kctx_storage; + + // Create wrapper structure + crypto_ec_key_wrapper_t *wrapper = os_calloc(1, sizeof(crypto_ec_key_wrapper_t)); + if (!wrapper) { + wpa_printf(MSG_ERROR, "Memory allocation failed for key wrapper"); return NULL; } - ret = mbedtls_pk_parse_key(kctx, privkey, privkey_len, NULL, 0, mbedtls_esp_random, NULL); + mbedtls_ecp_group_init(&wrapper->group); + wrapper->group.id = MBEDTLS_ECP_DP_NONE; + + mbedtls_pk_init(kctx); + ret = mbedtls_pk_parse_key(kctx, privkey, privkey_len, NULL, 0); if (ret < 0) { - //crypto_print_error_string(ret); goto fail; } - return (struct crypto_ec_key *)kctx; + // Get PSA attributes from parsed key to extract curve information + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + ret = mbedtls_pk_get_psa_attributes(kctx, PSA_KEY_USAGE_DERIVE, &key_attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_pk_get_psa_attributes failed with %d", ret); + goto fail; + } + + // Extract curve ID from PSA attributes + psa_key_type_t key_type = psa_get_key_type(&key_attributes); + psa_ecc_family_t ecc_family = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type); + int key_bits = psa_get_key_bits(&key_attributes); + if (ecc_family != 0 && key_bits > 0) { + // Map PSA ECC family to mbedtls curve ID + mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; + if (ecc_family == PSA_ECC_FAMILY_SECP_R1) { + if (key_bits == 256) { + grp_id = MBEDTLS_ECP_DP_SECP256R1; + } else if (key_bits == 384) { + grp_id = MBEDTLS_ECP_DP_SECP384R1; + } else if (key_bits == 521) { + grp_id = MBEDTLS_ECP_DP_SECP521R1; + } + } + wrapper->curve_id = grp_id; + } else { + wrapper->curve_id = MBEDTLS_ECP_DP_NONE; + } + + // Allow ECDH as enrollment algorithm for key agreement operations + // Note: While usage flags allow DERIVE, the algorithm policy must also permit ECDH. + // This enables keys imported by this function to be used for ECDH operations. + psa_set_key_enrollment_algorithm(&key_attributes, PSA_ALG_ECDH); + + ret = mbedtls_pk_import_into_psa(kctx, &key_attributes, &wrapper->key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_pk_import_into_psa failed with %d", ret); + goto fail; + } + + mbedtls_pk_free(kctx); + + return (struct crypto_ec_key *)wrapper; fail: mbedtls_pk_free(kctx); - os_free(kctx); + if (wrapper) { + if (wrapper->key_id != 0) { + psa_destroy_key(wrapper->key_id); + } + // Always free group since we always initialize it + mbedtls_ecp_group_free(&wrapper->group); + os_free(wrapper); + } return NULL; } -unsigned int crypto_ec_get_mbedtls_to_nist_group_id(int id) +unsigned int crypto_ec_get_mbedtls_to_nist_group_id(int id, int bits) { unsigned int nist_grpid = 0; switch (id) { - case MBEDTLS_ECP_DP_SECP256R1: - nist_grpid = 19; + case PSA_ECC_FAMILY_SECP_R1: + if (bits == 256) { + nist_grpid = 19; // NIST P-256 + } else if (bits == 384) { + nist_grpid = 20; // NIST P-384 + } else if (bits == 521) { + nist_grpid = 21; // NIST P-521 + } break; - case MBEDTLS_ECP_DP_SECP384R1: - nist_grpid = 20; - break; - case MBEDTLS_ECP_DP_SECP521R1: - nist_grpid = 21; - break; - case MBEDTLS_ECP_DP_BP256R1: - nist_grpid = 28; - break; - case MBEDTLS_ECP_DP_BP384R1: - nist_grpid = 29; - break; - case MBEDTLS_ECP_DP_BP512R1: - nist_grpid = 30; + case PSA_ECC_FAMILY_BRAINPOOL_P_R1: + if (bits == 256) { + nist_grpid = 28; // Brainpool P-256 + } else if (bits == 384) { + nist_grpid = 29; // Brainpool P-384 + } else if (bits == 512) { + nist_grpid = 30; // Brainpool P-512 + } break; default: break; } - return nist_grpid; } -int crypto_ec_get_curve_id(const struct crypto_ec_group *group) -{ - mbedtls_ecp_group *grp = (mbedtls_ecp_group *)group; - return (crypto_ec_get_mbedtls_to_nist_group_id(grp->id)); -} - int crypto_ecdh(struct crypto_ec_key *key_own, struct crypto_ec_key *key_peer, u8 *secret, size_t *secret_len) { - mbedtls_ecdh_context *ctx = NULL; - mbedtls_pk_context *own = (mbedtls_pk_context *)key_own; - mbedtls_pk_context *peer = (mbedtls_pk_context *)key_peer; - int ret = -1; + int ret = 0; + + crypto_ec_key_wrapper_t *peer_wrapper = (crypto_ec_key_wrapper_t *)key_peer; + crypto_ec_key_wrapper_t *own_wrapper = (crypto_ec_key_wrapper_t *)key_own; + if (!peer_wrapper || !own_wrapper) { + return -1; + } + + unsigned char *peer_key_buf = os_calloc(PSA_EXPORT_PUBLIC_KEY_MAX_SIZE, sizeof(uint8_t)); + if (!peer_key_buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + ret = -1; + goto fail; + } + + size_t peer_key_len = 0; + psa_status_t status = psa_export_public_key(peer_wrapper->key_id, peer_key_buf, PSA_EXPORT_PUBLIC_KEY_MAX_SIZE, &peer_key_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "psa_export_public_key failed with %d", status); + ret = -1; + goto fail; + } *secret_len = 0; - ctx = os_malloc(sizeof(*ctx)); - if (!ctx) { - wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_CTX_new failed: %s", - __func__); + size_t secret_length = 0; + + // Debug: Check key attributes before key agreement + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t attr_status = psa_get_key_attributes(own_wrapper->key_id, &key_attributes); + if (attr_status == PSA_SUCCESS) { + psa_key_usage_t usage = psa_get_key_usage_flags(&key_attributes); + psa_algorithm_t alg = psa_get_key_algorithm(&key_attributes); + psa_key_type_t key_type = psa_get_key_type(&key_attributes); + wpa_printf(MSG_DEBUG, "crypto_ecdh: key usage=0x%x, algorithm=0x%x, type=0x%x", + usage, alg, key_type); + printf("crypto_ecdh: key usage=0x%x, algorithm=0x%x, type=0x%x\n", + usage, alg, key_type); + psa_reset_key_attributes(&key_attributes); + } + + status = psa_raw_key_agreement(PSA_ALG_ECDH, own_wrapper->key_id, peer_key_buf, peer_key_len, secret, 66, &secret_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "psa_raw_key_agreement failed with %d", status); + printf("psa_raw_key_agreement failed with %d\n", status); + ret = -1; goto fail; } - mbedtls_ecdh_init(ctx); - /* No need to setup, done through mbedtls_ecdh_get_params */ - - /* set params from our key */ - if (mbedtls_ecdh_get_params(ctx, mbedtls_pk_ec(*own), MBEDTLS_ECDH_OURS) < 0) { - wpa_printf(MSG_ERROR, "failed to set our ecdh params"); - goto fail; - } - -#ifndef DPP_MAX_SHARED_SECRET_LEN -#define DPP_MAX_SHARED_SECRET_LEN 66 -#endif - /* set params from peers key */ - if (mbedtls_ecdh_get_params(ctx, mbedtls_pk_ec(*peer), MBEDTLS_ECDH_THEIRS) < 0) { - wpa_printf(MSG_ERROR, "failed to set peer's ecdh params"); - goto fail; - } - - if (mbedtls_ecdh_calc_secret(ctx, secret_len, secret, DPP_MAX_SHARED_SECRET_LEN, - mbedtls_esp_random, NULL) < 0) { - wpa_printf(MSG_ERROR, "failed to calculate secret"); - goto fail; - } - - if (*secret_len > DPP_MAX_SHARED_SECRET_LEN) { - wpa_printf(MSG_ERROR, "secret len=%d is too big", *secret_len); - goto fail; - } - - ret = 0; + *secret_len = secret_length; fail: - if (ctx) { - mbedtls_ecdh_free(ctx); - os_free(ctx); + if (peer_key_buf) { + os_free(peer_key_buf); } + return ret; } int crypto_ecdsa_get_sign(unsigned char *hash, const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_ec_key *csign, int hash_len) { - int ret = -1; - mbedtls_pk_context *pkey = (mbedtls_pk_context *)csign; - - mbedtls_ecdsa_context *ctx = os_malloc(sizeof(*ctx)); - if (!ctx) { - wpa_printf(MSG_ERROR, "failed to allcate memory"); + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)csign; + if (!wrapper) { return -1; } - mbedtls_ecdsa_init(ctx); - if (mbedtls_ecdsa_from_keypair(ctx, mbedtls_pk_ec(*pkey)) < 0) { - goto fail; + size_t key_size = hash_len / 2; + unsigned char signature[128]; // Max for P-521 + size_t signature_length = 0; + + psa_status_t status = psa_sign_hash(wrapper->key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hash_len, signature, sizeof(signature), &signature_length); + if (status != PSA_SUCCESS) { + printf("psa_sign_hash failed with %d\n", status); + return -1; } - ret = mbedtls_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), (mbedtls_mpi *)r, (mbedtls_mpi *)s, - &ctx->MBEDTLS_PRIVATE(d), hash, SHA256_MAC_LEN, mbedtls_esp_random, NULL); -fail: - mbedtls_ecdsa_free(ctx); - os_free(ctx); + // Extract r component + int ret = mbedtls_mpi_read_binary((mbedtls_mpi *)r, signature, key_size); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to parse r: -0x%04x", -ret); + return -1; + } - return ret; + // Extract s component + ret = mbedtls_mpi_read_binary((mbedtls_mpi *)s, signature + key_size, key_size); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to parse s: -0x%04x", -ret); + return -1; + } + + return 0; } int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *csign, @@ -815,166 +1323,235 @@ int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *csign, const u8 *r, size_t r_len, const u8 *s, size_t s_len) { - /* (mbedtls_ecdsa_context *) */ - mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)csign); - if (!ecp_kp) { + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)csign; + if (!wrapper) { return -1; } - struct crypto_bignum *rb = NULL, *sb = NULL; - rb = crypto_bignum_init_set(r, r_len); - sb = crypto_bignum_init_set(s, s_len); - - mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); - mbedtls_ecp_point *ecp_kp_q = &ecp_kp->MBEDTLS_PRIVATE(Q); - int ret = mbedtls_ecdsa_verify(ecp_kp_grp, hash, hlen, - ecp_kp_q, (mbedtls_mpi *)rb, (mbedtls_mpi *)sb); - if (ret != 0) { - wpa_printf(MSG_ERROR, "ecdsa verification failed"); - crypto_bignum_deinit(rb, 0); - crypto_bignum_deinit(sb, 0); - return ret; + u8 *sig = os_zalloc(r_len + s_len); + if (!sig) { + return -1; } - return ret; + os_memcpy(sig, r, r_len); + os_memcpy(sig + r_len, s, s_len); + + psa_status_t status = psa_verify_hash(wrapper->key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hlen, sig, r_len + s_len); + if (status != PSA_SUCCESS) { + printf("psa_verify_hash failed with %d\n", status); + os_free(sig); + return -1; + } + + os_free(sig); + + return 0; } void crypto_ec_key_debug_print(struct crypto_ec_key *key, const char *title) { -#if defined(CONFIG_LOG_DEFAULT_LEVEL_DEBUG) || defined(CONFIG_LOG_DEFAULT_LEVEL_VERBOSE) -#if defined(DEBUG_PRINT) - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(*pkey); - u8 x[32], y[32], d[32]; - wpa_printf(MSG_EXCESSIVE, "curve: %s", - mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name); - int len = mbedtls_mpi_size((mbedtls_mpi *)crypto_ec_get_prime((struct crypto_ec *)crypto_ec_get_group_from_key(key))); +#ifdef DEBUG_PRINT + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { + return; + } + + unsigned char pub[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE] = {0}; + size_t pub_len = 0; + psa_status_t status = psa_export_public_key(wrapper->key_id, pub, sizeof(pub), &pub_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "crypto_ec_key_debug_print: psa_export_public_key failed with %d", status); + return; + } + + wpa_hexdump(MSG_INFO, "public key:", pub, pub_len); + wpa_printf(MSG_INFO, "public key len: %d", pub_len); + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + status = psa_get_key_attributes(wrapper->key_id, &key_attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "crypto_ec_key_debug_print: psa_get_key_attributes failed with %d", status); + return; + } + + psa_key_type_t key_type = psa_get_key_type(&key_attributes); + psa_ecc_family_t ecc_family = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type); + size_t bits = psa_get_key_bits(&key_attributes); + wpa_printf(MSG_INFO, "bits: %d", bits); + wpa_printf(MSG_INFO, "psa_ecc_family: %d", ecc_family); + + psa_reset_key_attributes(&key_attributes); - wpa_printf(MSG_EXCESSIVE, "prime len is %d", len); - crypto_ec_point_to_bin((struct crypto_ec *)crypto_ec_get_group_from_key(key), crypto_ec_key_get_public_key(key), x, y); - crypto_bignum_to_bin(crypto_ec_key_get_private_key(key), - d, len, len); - wpa_hexdump(MSG_EXCESSIVE, "Q_x:", x, 32); - wpa_hexdump(MSG_EXCESSIVE, "Q_y:", y, 32); - wpa_hexdump(MSG_EXCESSIVE, "d: ", d, 32); -#endif #endif } +/** + * crypto_ec_parse_subpub_key - Parse ASN.1 SubjectPublicKey and import to PSA + * @p: Pointer to ASN.1 encoded SubjectPublicKey + * @len: Length of the ASN.1 data + * Returns: Pointer to crypto_ec_key (PSA key ID) or NULL on failure + * + * Note: Uses mbedtls for ASN.1 parsing (no PSA equivalent), but returns PSA key + */ struct crypto_ec_key *crypto_ec_parse_subpub_key(const unsigned char *p, size_t len) { - int ret; - mbedtls_pk_context *pkey = (mbedtls_pk_context *)crypto_alloc_key(); + // Use mbedtls_pk_parse_public_key() to parse SubjectPublicKeyInfo + // This is the recommended replacement for the deprecated mbedtls_pk_parse_subpubkey() + mbedtls_pk_context pk_ctx; + mbedtls_pk_init(&pk_ctx); - if (!pkey) { + int ret = mbedtls_pk_parse_public_key(&pk_ctx, p, len); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to parse SubjectPublicKeyInfo: -0x%04x", -ret); + mbedtls_pk_free(&pk_ctx); return NULL; } - ret = mbedtls_pk_parse_subpubkey((unsigned char **)&p, p + len, pkey); - if (ret == 0) { - return (struct crypto_ec_key *)pkey; + + // Get the EC keypair from the PK context + mbedtls_ecp_keypair *ec = (mbedtls_ecp_keypair *)(pk_ctx.MBEDTLS_PRIVATE(pk_ctx)); + if (!ec) { + wpa_printf(MSG_ERROR, "Failed to get EC keypair from parsed key"); + mbedtls_pk_free(&pk_ctx); + return NULL; } - mbedtls_pk_free(pkey); - os_free(pkey); - return NULL; + mbedtls_ecp_group_id grp_id = ec->MBEDTLS_PRIVATE(grp).id; + + // Convert mbedtls curve ID to PSA curve family and bits + size_t key_bits = 0; + psa_ecc_family_t ecc_family = group_id_to_psa(grp_id, &key_bits); + if (ecc_family == 0) { + wpa_printf(MSG_ERROR, "Unsupported or invalid curve: %d", grp_id); + mbedtls_pk_free(&pk_ctx); + return NULL; + } + + // Export public key in uncompressed format for PSA import + unsigned char pub_key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE] = {0}; + size_t pub_key_len = 0; + + ret = mbedtls_ecp_point_write_binary( + &ec->MBEDTLS_PRIVATE(grp), + &ec->MBEDTLS_PRIVATE(Q), + MBEDTLS_ECP_PF_UNCOMPRESSED, + &pub_key_len, + pub_key_buf, + sizeof(pub_key_buf) + ); + + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to export public key: -0x%04x", -ret); + mbedtls_pk_free(&pk_ctx); + return NULL; + } + + // Done with mbedtls temporary context + mbedtls_pk_free(&pk_ctx); + + // Create wrapper structure + crypto_ec_key_wrapper_t *wrapper = os_calloc(1, sizeof(crypto_ec_key_wrapper_t)); + if (!wrapper) { + wpa_printf(MSG_ERROR, "Memory allocation failed for key wrapper"); + return NULL; + } + wrapper->curve_id = grp_id; // Store curve ID + mbedtls_ecp_group_init(&wrapper->group); // Initialize group structure + wrapper->group.id = MBEDTLS_ECP_DP_NONE; // Mark as not loaded yet (lazy init) + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, + PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_family)); + psa_set_key_bits(&attributes, key_bits); + + psa_status_t status = psa_import_key(&attributes, pub_key_buf, pub_key_len, &wrapper->key_id); + psa_reset_key_attributes(&attributes); + + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to import key to PSA: %d", status); + mbedtls_ecp_group_free(&wrapper->group); + os_free(wrapper); + return NULL; + } + + return (struct crypto_ec_key *)wrapper; } +/** + * crypto_is_ec_key - Check if a key is an EC key + * @key: Pointer to crypto_ec_key (PSA key ID) + * Returns: 1 if key is an EC key, 0 otherwise + */ int crypto_is_ec_key(struct crypto_ec_key *key) { - int ret = mbedtls_pk_can_do((mbedtls_pk_context *)key, MBEDTLS_PK_ECKEY); - return ret; + if (!key) { + return 0; + } + + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = psa_get_key_attributes(wrapper->key_id, &attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_DEBUG, "Failed to get key attributes: %d", status); + return 0; + } + + psa_key_type_t key_type = psa_get_key_type(&attributes); + psa_reset_key_attributes(&attributes); + + // Check if it's an ECC key (public or private key pair) + return PSA_KEY_TYPE_IS_ECC(key_type) ? 1 : 0; } struct crypto_ec_key * crypto_ec_key_gen(u16 ike_group) { - mbedtls_pk_context *kctx = (mbedtls_pk_context *)crypto_alloc_key(); + size_t key_bit_length = 0; - if (!kctx) { - wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); + // Hardcoded this to match the current master implementation with mbedTLS + // That also enforces the use of the same curve for the key pair + psa_ecc_family_t ecc_family = PSA_ECC_FAMILY_SECP_R1; + key_bit_length = ESP_SUP_MAX_ECC_KEY_SIZE; + mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_SECP256R1; // P-256 + + // Create wrapper structure + crypto_ec_key_wrapper_t *wrapper = os_calloc(1, sizeof(crypto_ec_key_wrapper_t)); + if (!wrapper) { + wpa_printf(MSG_ERROR, "Memory allocation failed for key wrapper"); + return NULL; + } + wrapper->curve_id = curve_id; + mbedtls_ecp_group_init(&wrapper->group); + wrapper->group.id = MBEDTLS_ECP_DP_NONE; + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH)); + // Allow ECDH as enrollment algorithm for key agreement operations + // Note: While usage flags allow DERIVE, the algorithm policy must also permit ECDH. + // This enables keys created by this function to be used for ECDH operations. + psa_set_key_enrollment_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family)); + psa_set_key_bits(&key_attributes, key_bit_length); + + psa_status_t status = psa_generate_key(&key_attributes, &wrapper->key_id); + if (status != PSA_SUCCESS) { + os_free(wrapper); + psa_reset_key_attributes(&key_attributes); return NULL; } - if (mbedtls_pk_setup(kctx, - mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) != 0) { - goto fail; - } + psa_reset_key_attributes(&key_attributes); - mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(*kctx), //get this from argument - mbedtls_esp_random, NULL); - - return (struct crypto_ec_key *)kctx; -fail: - mbedtls_pk_free(kctx); - os_free(kctx); - return NULL; + return (struct crypto_ec_key *)wrapper; } -/* - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * } - */ -static int pk_write_ec_param(unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec) -{ - int ret; - size_t len = 0; - const char *oid; - size_t oid_len; - - if ((ret = mbedtls_oid_get_oid_by_ec_grp(ec->MBEDTLS_PRIVATE(grp).id, &oid, &oid_len)) != 0) { - return (ret); - } - - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len)); - - return ((int) len); -} - -static int pk_write_ec_pubkey_formatted(unsigned char **p, unsigned char *start, - mbedtls_ecp_keypair *ec, int format) -{ - int ret; - size_t len = 0; - unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; - - if ((ret = mbedtls_ecp_point_write_binary(&ec->MBEDTLS_PRIVATE(grp), &ec->MBEDTLS_PRIVATE(Q), - format, - &len, buf, sizeof(buf))) != 0) { - return (ret); - } - - if (*p < start || (size_t)(*p - start) < len) { - return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL); - } - - *p -= len; - memcpy(*p, buf, len); - - return ((int) len); -} - -int mbedtls_pk_write_pubkey_formatted(unsigned char **p, unsigned char *start, - const mbedtls_pk_context *key, int format) -{ - int ret; - size_t len = 0; - - if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) { - MBEDTLS_ASN1_CHK_ADD(len, pk_write_ec_pubkey_formatted(p, start, mbedtls_pk_ec(*key), format)); - } else { - return (MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE); - } - - return ((int) len); -} - -int crypto_pk_write_formatted_pubkey_der(mbedtls_pk_context *key, unsigned char *buf, size_t size, int format) +int crypto_pk_write_formatted_pubkey_der(psa_key_id_t key_id, unsigned char *buf, size_t size, int format) { int ret; unsigned char *c; - size_t len = 0, par_len = 0, oid_len; - const char *oid; + size_t len = 0, par_len = 0; if (size == 0) { return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL); @@ -982,61 +1559,137 @@ int crypto_pk_write_formatted_pubkey_der(mbedtls_pk_context *key, unsigned char c = buf + size; - ret = mbedtls_pk_write_pubkey_formatted(&c, buf, key, format); - - if (ret < 0) { - return ret; + // Export the public key directly from PSA using the key ID + unsigned char *point_buf = os_calloc(PSA_EXPORT_PUBLIC_KEY_MAX_SIZE, sizeof(unsigned char)); + if (!point_buf) { + return MBEDTLS_ERR_PK_ALLOC_FAILED; } - MBEDTLS_ASN1_CHK_ADD(len, ret); + size_t point_len = 0; + psa_status_t status = psa_export_public_key(key_id, point_buf, PSA_EXPORT_PUBLIC_KEY_MAX_SIZE, &point_len); + if (status != PSA_SUCCESS) { + os_free(point_buf); + wpa_printf(MSG_ERROR, "psa_export_public_key failed: %d", status); + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + } + + // If compressed format requested and we have uncompressed data, convert it + if (format == MBEDTLS_ECP_PF_COMPRESSED && point_len > 1 && point_buf[0] == 0x04) { + // Uncompressed format: 0x04 || X || Y + // Compressed format: 0x02/0x03 || X (based on Y's parity) + size_t coord_len = (point_len - 1) / 2; + unsigned char compressed[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + + // Determine compression prefix based on Y coordinate's last bit (LSB of last byte) + compressed[0] = 0x02 | (point_buf[point_len - 1] & 0x01); + os_memcpy(compressed + 1, point_buf + 1, coord_len); + point_len = coord_len + 1; + os_memcpy(point_buf, compressed, point_len); + } + + // Write point data to buffer + if (c - buf < (int)point_len) { + os_free(point_buf); + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + c -= point_len; + os_memcpy(c, point_buf, point_len); + len += point_len; + os_free(point_buf); + + // Add BIT STRING wrapper with padding byte if (c - buf < 1) { - return (MBEDTLS_ERR_ASN1_BUF_TOO_SMALL); + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; } - - /* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - */ *--c = 0; len += 1; MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_BIT_STRING)); - if ((ret = mbedtls_oid_get_oid_by_pk_alg(mbedtls_pk_get_type(key), - &oid, &oid_len)) != 0) { - return (ret); + // Get curve parameters from PSA key attributes and write curve OID + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + status = psa_get_key_attributes(key_id, &attributes); + if (status == PSA_SUCCESS) { + psa_key_type_t key_type = psa_get_key_type(&attributes); + size_t bits = psa_get_key_bits(&attributes); + psa_reset_key_attributes(&attributes); + + psa_ecc_family_t family = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type); + + // Map PSA curve to OID + const char *curve_oid = NULL; + size_t curve_oid_len = 0; + + // OID for secp256r1 (prime256v1): 1.2.840.10045.3.1.7 + static const char oid_secp256r1[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}; + // OID for secp384r1: 1.3.132.0.34 + static const char oid_secp384r1[] = {0x2B, 0x81, 0x04, 0x00, 0x22}; + // OID for secp521r1: 1.3.132.0.35 + static const char oid_secp521r1[] = {0x2B, 0x81, 0x04, 0x00, 0x23}; + + if (family == PSA_ECC_FAMILY_SECP_R1) { + if (bits == 256) { + curve_oid = oid_secp256r1; + curve_oid_len = sizeof(oid_secp256r1); + } else if (bits == 384) { + curve_oid = oid_secp384r1; + curve_oid_len = sizeof(oid_secp384r1); + } else if (bits == 521) { + curve_oid = oid_secp521r1; + curve_oid_len = sizeof(oid_secp521r1); + } + } + + if (curve_oid) { + MBEDTLS_ASN1_CHK_ADD(par_len, mbedtls_asn1_write_oid(&c, buf, curve_oid, curve_oid_len)); + } } - if (mbedtls_pk_get_type(key) == MBEDTLS_PK_ECKEY) { - MBEDTLS_ASN1_CHK_ADD(par_len, pk_write_ec_param(&c, buf, mbedtls_pk_ec(*key))); - } + // OID for id-ecPublicKey: 1.2.840.10045.2.1 + static const char oid_ec_pubkey[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01}; - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier(&c, buf, oid, oid_len, + // Write algorithm identifier with parameters + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier(&c, buf, + oid_ec_pubkey, + sizeof(oid_ec_pubkey), par_len)); + // Write outer SEQUENCE MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); - MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); - return ((int) len); + return (int) len; } int crypto_ec_write_pub_key(struct crypto_ec_key *key, unsigned char **key_buf) { - unsigned char output_buf[1600] = {0}; - int len = crypto_pk_write_formatted_pubkey_der((mbedtls_pk_context *)key, output_buf, 1600, 1); + + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { + return 0; + } + + unsigned char *output_buf = os_zalloc(1600); + if (!output_buf) { + wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); + return 0; + } + + int len = crypto_pk_write_formatted_pubkey_der(wrapper->key_id, output_buf, 1600, 1); if (len <= 0) { + os_free(output_buf); return 0; } *key_buf = os_malloc(len); if (!*key_buf) { wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); + os_free(output_buf); return 0; } os_memcpy(*key_buf, output_buf + 1600 - len, len); + os_free(output_buf); return len; } @@ -1051,6 +1704,8 @@ struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) if (!der) { wpa_printf(MSG_ERROR, "failed to get der for bootstrapping key\n"); return NULL; + } else { + wpa_printf(MSG_DEBUG, "der_len: %d\n", der_len); } ret = wpabuf_alloc_copy(der, der_len); @@ -1074,167 +1729,199 @@ int crypto_mbedtls_get_grp_id(int group) void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) { - mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh; - if (!ctx) { + if (!ecdh) { return; } - mbedtls_ecdh_free(ctx); - os_free(ctx); - ctx = NULL; + psa_key_id_t *key_id = (psa_key_id_t *)ecdh; + psa_destroy_key(*key_id); + os_free(key_id); } struct crypto_ecdh * crypto_ecdh_init(int group) { - mbedtls_ecdh_context *ctx; - - ctx = os_zalloc(sizeof(*ctx)); - if (!ctx) { - wpa_printf(MSG_ERROR, "Memory allocation failed for ecdh context"); - goto fail; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t *key_id = os_calloc(1, sizeof(psa_key_id_t)); + if (!key_id) { + return NULL; } - mbedtls_ecdh_init(ctx); -#ifndef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT - ctx->MBEDTLS_PRIVATE(var) = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; -#endif + size_t key_size = 0; - if ((mbedtls_ecp_group_load(ACCESS_ECDH(&ctx, grp), crypto_mbedtls_get_grp_id(group))) != 0) { - wpa_printf(MSG_ERROR, "Failed to set up ECDH context with group info"); - goto fail; + psa_ecc_family_t ecc_family = group_id_to_psa(crypto_mbedtls_get_grp_id(group), &key_size); + if (ecc_family == 0) { + os_free(key_id); + wpa_printf(MSG_ERROR, "group_id_to_psa failed, group: %d", group); + return NULL; } - /* Generates ECDH keypair on elliptic curve */ - if (mbedtls_ecdh_gen_public(ACCESS_ECDH(&ctx, grp), ACCESS_ECDH(&ctx, d), ACCESS_ECDH(&ctx, Q), mbedtls_esp_random, NULL) != 0) { - wpa_printf(MSG_ERROR, "ECDH keypair on curve failed"); - goto fail; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family)); + psa_set_key_bits(&key_attributes, key_size); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + + psa_status_t status = psa_generate_key(&key_attributes, key_id); + if (status != PSA_SUCCESS) { + os_free(key_id); + psa_reset_key_attributes(&key_attributes); + return NULL; } - return (struct crypto_ecdh *)ctx; -fail: - if (ctx) { - mbedtls_ecdh_free(ctx); - os_free(ctx); - ctx = NULL; - } - return NULL; + psa_reset_key_attributes(&key_attributes); + + return (struct crypto_ecdh *)key_id; } struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int y) { struct wpabuf *public_key = NULL; - uint8_t *buf = NULL; - int ret; - mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh; - size_t prime_len = ACCESS_ECDH(ctx, grp).pbits / 8; + psa_key_id_t *key_id = (psa_key_id_t *)ecdh; - buf = os_zalloc(y ? prime_len : 2 * prime_len); - if (!buf) { - wpa_printf(MSG_ERROR, "Memory allocation failed"); + size_t key_size = 0; + + uint8_t raw_key[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE] = {0}; + + psa_status_t status = psa_export_public_key(*key_id, raw_key, sizeof(raw_key), &key_size); + if (status != PSA_SUCCESS) { return NULL; } - /* Export an MPI into unsigned big endian binary data of fixed size */ - ret = mbedtls_mpi_write_binary(ACCESS_ECDH(&ctx, Q).MBEDTLS_PRIVATE(X), buf, prime_len); - if (ret) { - goto cleanup; + size_t coord_size = (key_size - 1) / 2; + if (y) { + public_key = wpabuf_alloc_copy(raw_key + 1, key_size - 1); + } else { + public_key = wpabuf_alloc_copy(raw_key + 1, coord_size); } - public_key = wpabuf_alloc_copy(buf, 32); -cleanup: - os_free(buf); return public_key; } struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, const u8 *key, size_t len) { - uint8_t *secret = 0; - size_t olen = 0, len_prime = 0; - struct crypto_bignum *bn_x = NULL; - struct crypto_ec_point *ec_pt = NULL; - uint8_t *px = NULL, *py = NULL, *buf = NULL; - struct crypto_ec_key *pkey = NULL; - struct wpabuf *sh_secret = NULL; - int secret_key = 0; + psa_key_id_t *key_id = (psa_key_id_t *)ecdh; - mbedtls_ecdh_context *ctx = (mbedtls_ecdh_context *)ecdh; - if (!ctx) { - wpa_printf(MSG_ERROR, "ECDH Context is NULL"); - return 0; - } - - len_prime = ACCESS_ECDH(ctx, grp).pbits / 8; - bn_x = crypto_bignum_init_set(key, len); - - /* Initialize data for EC point */ - ec_pt = crypto_ec_point_init((struct crypto_ec*)ACCESS_ECDH(&ctx, grp)); - if (!ec_pt) { - wpa_printf(MSG_ERROR, "Initializing for EC point failed"); - goto cleanup; - } - - if (crypto_ec_point_solve_y_coord((struct crypto_ec *)ACCESS_ECDH(&ctx, grp), ec_pt, bn_x, inc_y) != 0) { - wpa_printf(MSG_ERROR, "Failed to solve for y coordinate"); - goto cleanup; - } - px = os_zalloc(len); - py = os_zalloc(len); - buf = os_zalloc(2 * len); - - if (!px || !py || !buf) { - wpa_printf(MSG_ERROR, "Memory allocation failed"); - goto cleanup; - } - if (crypto_ec_point_to_bin((struct crypto_ec *)ACCESS_ECDH(&ctx, grp), ec_pt, px, py) != 0) { - wpa_printf(MSG_ERROR, "Failed to write EC point value as binary data"); - goto cleanup; - } - - os_memcpy(buf, px, len); - os_memcpy(buf + len, py, len); - - pkey = crypto_ec_key_set_pub((struct crypto_ec_group*)ACCESS_ECDH(&ctx, grp), buf, len); - if (!pkey) { - wpa_printf(MSG_ERROR, "Failed to set point for peer's public key"); - goto cleanup; - } - - mbedtls_pk_context *peer = (mbedtls_pk_context*)pkey; - - /* Setup ECDH context from EC key */ - /* Call to mbedtls_ecdh_get_params() will initialize the context when not LEGACY context */ - if (peer != NULL) { - mbedtls_ecp_copy(ACCESS_ECDH(&ctx, Qp), &(mbedtls_pk_ec(*peer))->MBEDTLS_PRIVATE(Q)); -#ifndef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT - ctx->MBEDTLS_PRIVATE(var) = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; -#endif - } else { - wpa_printf(MSG_ERROR, "Failed to set peer's ECDH context"); - goto cleanup; - } - int len_secret = inc_y ? 2 * len : len; - secret = os_zalloc(len_secret); + size_t secret_len = inc_y ? 2 * len : len; + uint8_t *secret = os_zalloc(secret_len); if (!secret) { - wpa_printf(MSG_ERROR, "Allocation failed for secret"); - goto cleanup; + return NULL; + } + size_t secret_length = 0; + + /* PSA expects peer public key in uncompressed format: 0x04 || X || Y + * For OWE (inc_y=0), we only have X coordinate - but PSA requires full uncompressed format. + * For full keys (inc_y=1), we have X || Y and need to prepend 0x04. + */ + uint8_t *peer_key_buf = NULL; + size_t peer_key_len = 0; + + if (inc_y) { + /* Full public key: prepend 0x04 prefix for uncompressed format */ + peer_key_len = 1 + len; /* len should be 64 for P-256 (X+Y) */ + peer_key_buf = os_zalloc(peer_key_len); + if (!peer_key_buf) { + os_free(secret); + return NULL; + } + peer_key_buf[0] = 0x04; /* Uncompressed point format */ + os_memcpy(peer_key_buf + 1, key, len); + } else { + /* Only X coordinate provided (OWE case): need to convert to uncompressed format + * RFC 8110: OWE transmits only X coordinate (32 bytes for P-256). + * PSA expects uncompressed format: 0x04 || X || Y (65 bytes for P-256). + * Use mbedtls to convert compressed (0x02 || X) to uncompressed (0x04 || X || Y). + */ + mbedtls_ecp_group grp; + mbedtls_ecp_point pt; + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&pt); + + int ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to load ECC group: -0x%04x", -ret); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + os_free(secret); + return NULL; + } + + /* Create compressed format buffer: 0x02 || X (assuming even Y) */ + uint8_t *compressed = os_zalloc(1 + len); + if (!compressed) { + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + os_free(secret); + return NULL; + } + compressed[0] = 0x02; /* Compressed format with even Y */ + os_memcpy(compressed + 1, key, len); + + /* Parse compressed point - mbedtls will compute Y from X */ + ret = mbedtls_ecp_point_read_binary(&grp, &pt, compressed, 1 + len); + os_free(compressed); + + if (ret != 0) { + /* Try with odd Y (0x03) if even Y failed */ + compressed = os_zalloc(1 + len); + if (!compressed) { + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + os_free(secret); + return NULL; + } + compressed[0] = 0x03; /* Compressed format with odd Y */ + os_memcpy(compressed + 1, key, len); + + ret = mbedtls_ecp_point_read_binary(&grp, &pt, compressed, 1 + len); + os_free(compressed); + + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to parse compressed ECC point: -0x%04x", -ret); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + os_free(secret); + return NULL; + } + } + + /* Export point in uncompressed format: 0x04 || X || Y */ + peer_key_len = 1 + 2 * len; /* 65 bytes for P-256 */ + peer_key_buf = os_zalloc(peer_key_len); + if (!peer_key_buf) { + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + os_free(secret); + return NULL; + } + + size_t olen = 0; + ret = mbedtls_ecp_point_write_binary(&grp, &pt, MBEDTLS_ECP_PF_UNCOMPRESSED, + &olen, peer_key_buf, peer_key_len); + if (ret != 0 || olen != peer_key_len) { + wpa_printf(MSG_ERROR, "Failed to export uncompressed ECC point: -0x%04x", -ret); + os_free(peer_key_buf); + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); + os_free(secret); + return NULL; + } + + mbedtls_ecp_point_free(&pt); + mbedtls_ecp_group_free(&grp); } - /* Calculate secret - z = F(DH(x,Y)) */ - secret_key = mbedtls_ecdh_calc_secret(ctx, &olen, secret, len_prime, mbedtls_esp_random, NULL); - if (secret_key != 0) { - wpa_printf(MSG_ERROR, "Calculation of secret failed"); - goto cleanup; - } - sh_secret = wpabuf_alloc_copy(secret, len_secret); + psa_status_t status = psa_raw_key_agreement(PSA_ALG_ECDH, *key_id, peer_key_buf, peer_key_len, + secret, secret_len, &secret_length); + os_free(peer_key_buf); + + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "psa_raw_key_agreement failed with PSA error 0x%x", status); + os_free(secret); + return NULL; + } + + struct wpabuf *sh_secret = wpabuf_alloc_copy(secret, secret_len); -cleanup: - os_free(px); - os_free(py); - os_free(buf); os_free(secret); - crypto_ec_key_deinit(pkey); - crypto_bignum_deinit(bn_x, 1); - crypto_ec_point_deinit(ec_pt, 1); + return sh_secret; } @@ -1255,49 +1942,147 @@ struct crypto_ec_key *crypto_ec_key_parse_pub(const u8 *der, size_t der_len) os_free(pkey); return NULL; } - return (struct crypto_ec_key *)pkey; + + // Extract curve ID from parsed key + mbedtls_ecp_keypair *ec = (mbedtls_ecp_keypair *)(pkey->MBEDTLS_PRIVATE(pk_ctx)); + mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE; + if (ec) { + grp_id = ec->MBEDTLS_PRIVATE(grp).id; + } + + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + ret = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_VERIFY_HASH, &key_attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_pk_get_psa_attributes failed with %d", ret); + mbedtls_pk_free(pkey); + os_free(pkey); + return NULL; + } + + // Create wrapper structure + crypto_ec_key_wrapper_t *wrapper = os_calloc(1, sizeof(crypto_ec_key_wrapper_t)); + if (!wrapper) { + wpa_printf(MSG_ERROR, "Memory allocation failed for key wrapper"); + mbedtls_pk_free(pkey); + os_free(pkey); + return NULL; + } + wrapper->curve_id = grp_id; // Store curve ID + mbedtls_ecp_group_init(&wrapper->group); + wrapper->group.id = MBEDTLS_ECP_DP_NONE; // Mark as not loaded yet (lazy init) + + ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &wrapper->key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_pk_import_into_psa failed with %d", ret); + mbedtls_ecp_group_free(&wrapper->group); + os_free(wrapper); + mbedtls_pk_free(pkey); + os_free(pkey); + return NULL; + } + psa_reset_key_attributes(&key_attributes); + mbedtls_pk_free(pkey); + os_free(pkey); + + return (struct crypto_ec_key *)wrapper; } void crypto_ec_key_deinit(struct crypto_ec_key *key) { - mbedtls_pk_free((mbedtls_pk_context *)key); - os_free(key); + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (wrapper == NULL) { + return; + } + if (wrapper->key_id != 0) { + psa_destroy_key(wrapper->key_id); + } + // Free the group if it was initialized + if (wrapper->group.id != MBEDTLS_ECP_DP_NONE) { + mbedtls_ecp_group_free(&wrapper->group); + } + // Free cached public key point if allocated + if (wrapper->cached_public_key) { + mbedtls_ecp_point_free(wrapper->cached_public_key); + os_free(wrapper->cached_public_key); + } + // Free cached private key bignum if allocated + if (wrapper->cached_private_key) { + mbedtls_mpi_free(wrapper->cached_private_key); + os_free(wrapper->cached_private_key); + } + os_free(wrapper); } int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, size_t len, const u8 *sig, size_t sig_len) { - int ret = 0; - - mbedtls_ecdsa_context *ctx_verify = os_malloc(sizeof(mbedtls_ecdsa_context)); - if (!ctx_verify) { + crypto_ec_key_wrapper_t *wrapper = (crypto_ec_key_wrapper_t *)key; + if (!wrapper) { return -1; } - mbedtls_ecdsa_init(ctx_verify); - - mbedtls_ecp_keypair *ec_key = mbedtls_pk_ec(*((mbedtls_pk_context *)key)); - mbedtls_ecp_group *grp = &ec_key->MBEDTLS_PRIVATE(grp); - - if ((ret = mbedtls_ecp_group_copy(&ctx_verify->MBEDTLS_PRIVATE(grp), grp)) != 0) { - goto cleanup; + /* Get key attributes to extract key_bits needed for DER-to-raw conversion */ + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = psa_get_key_attributes(wrapper->key_id, &key_attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "crypto_ec_key_verify_signature: psa_get_key_attributes failed: %d", status); + psa_reset_key_attributes(&key_attributes); + return -1; } - if ((ret = mbedtls_ecp_copy(&ctx_verify->MBEDTLS_PRIVATE(Q), &ec_key->MBEDTLS_PRIVATE(Q))) != 0) { - goto cleanup; + size_t key_bits = psa_get_key_bits(&key_attributes); + psa_reset_key_attributes(&key_attributes); + + /* Determine hash algorithm from data length */ + psa_algorithm_t verify_alg; + if (len == 32) { + verify_alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256); + } else if (len == 48) { + verify_alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384); + } else if (len == 64) { + verify_alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_512); + } else if (len == 20) { + verify_alg = PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_1); + } else { + wpa_printf(MSG_ERROR, "crypto_ec_key_verify_signature: Unsupported hash length %d", (int)len); + return -1; } - if ((ret = mbedtls_ecdsa_read_signature(ctx_verify, - data, len, - sig, sig_len)) != 0) { - goto cleanup; - } - ret = 1; + /* Convert DER-encoded signature to raw format (r||s) for PSA */ + /* PSA verify_hash expects raw format, not DER format */ + /* API specification requires DER format input */ + /* Raw signature length = 2 * PSA_BITS_TO_BYTES(key_bits), max 132 bytes for P-521 */ + unsigned char raw_sig[132]; + size_t raw_sig_len = 0; + const u8 *sig_to_verify = sig; + size_t sig_len_to_verify = sig_len; -cleanup: - mbedtls_ecdsa_free(ctx_verify); - os_free(ctx_verify); - return ret; + /* Check if signature is DER format (starts with 0x30) */ + if (sig_len > 0 && sig[0] == 0x30) { + /* Convert DER to raw format */ + int ret = mbedtls_ecdsa_der_to_raw(key_bits, sig, sig_len, + raw_sig, sizeof(raw_sig), &raw_sig_len); + if (ret != 0) { + wpa_printf(MSG_ERROR, "crypto_ec_key_verify_signature: Failed to convert DER to raw format: %d", ret); + return -1; + } + sig_to_verify = raw_sig; + sig_len_to_verify = raw_sig_len; + } else { + /* Signature must be in DER format as per API specification */ + wpa_printf(MSG_ERROR, "crypto_ec_key_verify_signature: Invalid signature format (expected DER, got 0x%02x)", sig_len > 0 ? sig[0] : 0); + return -1; + } + + /* Perform signature verification */ + status = psa_verify_hash(wrapper->key_id, verify_alg, + data, len, sig_to_verify, sig_len_to_verify); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "crypto_ec_key_verify_signature: psa_verify_hash failed: %d", status); + return -1; + } + + return 1; } #endif /* CONFIG_ECC */ diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c index 649e860a3c2..77dcd224736 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-rsa.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,10 +15,16 @@ #include "common/defs.h" #ifdef CONFIG_CRYPTO_MBEDTLS +// #include "mbedtls/entropy.h" +// #include "mbedtls/ctr_drbg.h" + #include #include #include -#include +// #include + +#include "psa/crypto.h" +#include /* Dummy structures; these are just typecast to struct crypto_rsa_key */ struct crypto_public_key; @@ -118,7 +124,7 @@ struct crypto_private_key * crypto_private_key_import(const u8 *key, mbedtls_pk_init(pkey); ret = mbedtls_pk_parse_key(pkey, key, len, (const unsigned char *)passwd, - passwd ? os_strlen(passwd) : 0, mbedtls_esp_random, NULL); + passwd ? os_strlen(passwd) : 0); if (ret < 0) { wpa_printf(MSG_ERROR, "failed to parse private key"); @@ -154,18 +160,31 @@ struct crypto_public_key *crypto_public_key_from_cert(const u8 *buf, goto fail; } + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + ret = mbedtls_pk_get_psa_attributes(&cert->pk, PSA_KEY_USAGE_VERIFY_HASH, &key_attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", ret); + goto fail; + } + + ret = mbedtls_pk_import_into_psa(&cert->pk, &key_attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret); + goto fail; + } + mbedtls_pk_init(kctx); - if (mbedtls_pk_setup(kctx, mbedtls_pk_info_from_type(mbedtls_pk_get_type(&cert->pk))) != 0) { - wpa_printf(MSG_ERROR, "key setup failed"); + // Load the key from PSA into mbedTLS pk context + ret = mbedtls_pk_copy_from_psa(key_id, kctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to copy key from PSA, returned %d", ret); goto fail; } - ret = mbedtls_rsa_copy(mbedtls_pk_rsa(*kctx), mbedtls_pk_rsa(cert->pk)); - if (ret < 0) { - wpa_printf(MSG_ERROR, "key copy failed"); - goto fail; - } + psa_destroy_key(key_id); + psa_reset_key_attributes(&key_attributes); cleanup: mbedtls_x509_crt_free(cert); @@ -181,23 +200,51 @@ int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { - int ret; - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + int ret = 0; - if (!pkey) { - return -1; - } + mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - ret = mbedtls_rsa_pkcs1_encrypt(mbedtls_pk_rsa(*pkey), mbedtls_esp_random, - NULL, inlen, in, out); + // Load the key into PSA + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; - if (ret != 0) { - wpa_printf(MSG_ERROR, " failed ! mbedtls_rsa_pkcs1_encrypt returned -0x%04x", -ret); + psa_status_t status = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_ENCRYPT, &key_attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", (int) status); + ret = -1; goto cleanup; } - *outlen = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey)); + + // If we have a private key but need public key for encryption, modify attributes + psa_key_type_t key_type = psa_get_key_type(&key_attributes); + if (PSA_KEY_TYPE_IS_KEY_PAIR(key_type)) { + // We have a key pair, but encryption needs the public key + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type)); + wpa_printf(MSG_DEBUG, "Converting key pair to public key for encryption"); + } + + ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret); + ret = -1; + goto cleanup; + } + + size_t output_len = 0; + status = psa_asymmetric_encrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, in, inlen, NULL, 0, out, *outlen, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to encrypt data, returned %d", (int) status); + ret = -1; + goto cleanup; + } + + *outlen = output_len; cleanup: + psa_reset_key_attributes(&key_attributes); + if (key_id) { + psa_destroy_key(key_id); + } return ret; } @@ -205,22 +252,41 @@ int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { - int ret; - size_t i; - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + int ret = 0; + mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - if (!pkey) { - return -1; + // Load the key into PSA + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status_t status = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_DECRYPT, &key_attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", (int) status); + ret = -1; + goto cleanup; } - i = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey)); - ret = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_pk_rsa(*pkey), mbedtls_esp_random, - NULL, &i, in, out, *outlen); - - if (ret == 0) { - *outlen = i; + ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret); + ret = -1; + 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) { + wpa_printf(MSG_ERROR, "Failed to decrypt data, returned %d", (int) status); + ret = -1; + goto cleanup; + } + *outlen = output_len; + +cleanup: + psa_reset_key_attributes(&key_attributes); + if (key_id) { + psa_destroy_key(key_id); + } return ret; } @@ -228,25 +294,108 @@ int crypto_private_key_sign_pkcs1(struct crypto_private_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen) { - int ret; - mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; + int ret = 0; - if (!pkey) { - return -1; - } + mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - if ((ret = mbedtls_rsa_pkcs1_sign(mbedtls_pk_rsa(*pkey), mbedtls_esp_random, NULL, - (mbedtls_pk_rsa(*pkey))->MBEDTLS_PRIVATE(hash_id), - inlen, in, out)) != 0) { - wpa_printf(MSG_ERROR, " failed ! mbedtls_rsa_pkcs1_sign returned %d", ret); + // Load the key into PSA + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status_t status = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_SIGN_HASH, &key_attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", (int) status); + ret = -1; goto cleanup; } - *outlen = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey)); + + ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret); + ret = -1; + goto cleanup; + } + + size_t output_len = 0; + status = psa_sign_hash(key_id, PSA_ALG_RSA_PKCS1V15_SIGN_RAW, in, inlen, out, *outlen, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to sign data, returned %d", (int) status); + ret = -1; + goto cleanup; + } + + *outlen = output_len; cleanup: + psa_reset_key_attributes(&key_attributes); + if (key_id) { + psa_destroy_key(key_id); + } return ret; } +struct crypto_public_key *crypto_public_key_from_private_key(struct crypto_private_key *priv_key) +{ + if (!priv_key) { + return NULL; + } + + mbedtls_pk_context *priv_ctx = (mbedtls_pk_context *)priv_key; + mbedtls_pk_context *pub_ctx = os_zalloc(sizeof(mbedtls_pk_context)); + + if (!pub_ctx) { + wpa_printf(MSG_ERROR, "Failed to allocate memory for public key"); + return NULL; + } + + // Import the private key into PSA temporarily to extract the public key + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + // Use a valid usage flag - mbedtls_pk_get_psa_attributes will automatically add EXPORT + // We use DECRYPT as a generic private key operation to get the key attributes + int ret = mbedtls_pk_get_psa_attributes(priv_ctx, PSA_KEY_USAGE_DECRYPT, &key_attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", ret); + os_free(pub_ctx); + return NULL; + } + + ret = mbedtls_pk_import_into_psa(priv_ctx, &key_attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to import private key, returned %d", ret); + psa_reset_key_attributes(&key_attributes); + os_free(pub_ctx); + return NULL; + } + + // Export the public key + unsigned char pub_key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE]; + size_t pub_key_len = 0; + psa_status_t status = psa_export_public_key(key_id, pub_key_buf, sizeof(pub_key_buf), &pub_key_len); + + psa_destroy_key(key_id); + psa_reset_key_attributes(&key_attributes); + + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to export public key, returned %d", (int) status); + os_free(pub_ctx); + return NULL; + } + + // Parse the public key into a new pk context + mbedtls_pk_init(pub_ctx); + ret = mbedtls_pk_parse_public_key(pub_ctx, pub_key_buf, pub_key_len); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to parse public key, returned %d", ret); + mbedtls_pk_free(pub_ctx); + os_free(pub_ctx); + return NULL; + } + + return (struct crypto_public_key *)pub_ctx; +} + void crypto_public_key_free(struct crypto_public_key *key) { mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; @@ -276,15 +425,46 @@ int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key, size_t len; u8 *pos; mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - len = mbedtls_pk_rsa(*pkey)->MBEDTLS_PRIVATE(len); - if (len != crypt_len) { + + // Load the key into PSA + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + int ret = mbedtls_pk_get_psa_attributes(pkey, PSA_KEY_USAGE_DECRYPT, &key_attributes); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to get key attributes, returned %d", ret); + psa_reset_key_attributes(&key_attributes); return -1; } - if (mbedtls_rsa_public(mbedtls_pk_rsa(*pkey), crypt, plain) < 0) { + len = psa_get_key_bits(&key_attributes) / 8; + if (len != crypt_len) { + psa_reset_key_attributes(&key_attributes); return -1; } + ret = mbedtls_pk_import_into_psa(pkey, &key_attributes, &key_id); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to import key, returned %d", ret); + psa_reset_key_attributes(&key_attributes); + return -1; + } + psa_reset_key_attributes(&key_attributes); + + size_t output_len = 0; + status = psa_asymmetric_decrypt(key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, crypt, crypt_len, NULL, 0, plain, *plain_len, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "Failed to decrypt data, returned %d", (int) status); + psa_destroy_key(key_id); + return -1; + } + + *plain_len = output_len; + + if (key_id) { + psa_destroy_key(key_id); + } + /* * PKCS #1 v1.5, 8.1: * diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c index 89653b789fc..55077212fb8 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#define MBEDTLS_ALLOW_PRIVATE_ACCESS + #ifdef ESP_PLATFORM #include "esp_system.h" #endif @@ -16,13 +19,8 @@ #include "mbedtls/ecp.h" #include "mbedtls/md.h" -#include "mbedtls/aes.h" #include "mbedtls/bignum.h" -#include "mbedtls/pkcs5.h" -#include "mbedtls/cmac.h" #include "mbedtls/nist_kw.h" -#include "mbedtls/des.h" -#include "mbedtls/ccm.h" #include "common.h" #include "utils/wpabuf.h" @@ -34,106 +32,84 @@ #include "aes_wrap.h" #include "crypto.h" #include "mbedtls/esp_config.h" -#include "mbedtls/sha1.h" + +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" #ifdef CONFIG_FAST_PBKDF2 #include "fastpbkdf2.h" #include "fastpsk.h" #endif -static int digest_vector(mbedtls_md_type_t md_type, size_t num_elem, +struct crypto_hash { + union { + psa_hash_operation_t *hash_operation; + psa_mac_operation_t *mac_operation; + } u; + int is_mac; + psa_key_id_t key_id; +}; + +static int digest_vector(psa_algorithm_t alg, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - size_t i; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + psa_status_t status; + int ret = -1; - mbedtls_md_init(&md_ctx); - - md_info = mbedtls_md_info_from_type(md_type); - if (!md_info) { - wpa_printf(MSG_ERROR, "mbedtls_md_info_from_type() failed"); - return -1; - } - - ret = mbedtls_md_setup(&md_ctx, md_info, 0); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_md_setup() returned error"); + status = psa_hash_setup(&operation, alg); + if (status != PSA_SUCCESS) { goto cleanup; } - ret = mbedtls_md_starts(&md_ctx); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_md_starts returned error"); - goto cleanup; - } - - for (i = 0; i < num_elem; i++) { - ret = mbedtls_md_update(&md_ctx, addr[i], len[i]); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_md_update ret=%d", ret); + for (size_t i = 0; i < num_elem; i++) { + status = psa_hash_update(&operation, addr[i], len[i]); + if (status != PSA_SUCCESS) { goto cleanup; } } - ret = mbedtls_md_finish(&md_ctx, mac); + size_t mac_len; + status = psa_hash_finish(&operation, mac, PSA_HASH_LENGTH(alg), &mac_len); + if (status != PSA_SUCCESS) { + goto cleanup; + } + + ret = 0; + cleanup: - mbedtls_md_free(&md_ctx); - + psa_hash_abort(&operation); return ret; - } int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return digest_vector(MBEDTLS_MD_SHA256, num_elem, addr, len, mac); + return digest_vector(PSA_ALG_SHA_256, num_elem, addr, len, mac); } int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return digest_vector(MBEDTLS_MD_SHA384, num_elem, addr, len, mac); + return digest_vector(PSA_ALG_SHA_384, num_elem, addr, len, mac); } int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return digest_vector(MBEDTLS_MD_SHA512, num_elem, addr, len, mac); + return digest_vector(PSA_ALG_SHA_512, num_elem, addr, len, mac); } #if CONFIG_MBEDTLS_SHA1_C || CONFIG_MBEDTLS_HARDWARE_SHA int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { -#if defined(MBEDTLS_SHA1_C) - return digest_vector(MBEDTLS_MD_SHA1, num_elem, addr, len, mac); -#elif defined(MBEDTLS_SHA1_ALT) - mbedtls_sha1_context ctx; - size_t i; - int ret; - - mbedtls_sha1_init(&ctx); - for (i = 0; i < num_elem; i++) { - ret = mbedtls_sha1_update(&ctx, addr[i], len[i]); - if (ret != 0) { - goto exit; - } - } - ret = mbedtls_sha1_finish(&ctx, mac); - -exit: - mbedtls_sha1_free(&ctx); - return ret; -#else - return -ENOTSUP; -#endif + return digest_vector(PSA_ALG_SHA_1, num_elem, addr, len, mac); } #endif int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return digest_vector(MBEDTLS_MD_MD5, num_elem, addr, len, mac); + return digest_vector(PSA_ALG_MD5, num_elem, addr, len, mac); } #ifdef MBEDTLS_MD4_C @@ -146,32 +122,35 @@ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, size_t key_len) { - mbedtls_md_context_t *ctx = NULL; - mbedtls_md_type_t md_type; - const mbedtls_md_info_t *md_info; - int ret; + struct crypto_hash *ctx = os_zalloc(sizeof(struct crypto_hash)); + if (ctx == NULL) { + return NULL; + } + + psa_algorithm_t psa_alg; int is_hmac = 0; switch (alg) { case CRYPTO_HASH_ALG_MD5: case CRYPTO_HASH_ALG_HMAC_MD5: - md_type = MBEDTLS_MD_MD5; + psa_alg = PSA_ALG_MD5; break; case CRYPTO_HASH_ALG_SHA1: case CRYPTO_HASH_ALG_HMAC_SHA1: - md_type = MBEDTLS_MD_SHA1; + psa_alg = PSA_ALG_SHA_1; break; case CRYPTO_HASH_ALG_SHA256: case CRYPTO_HASH_ALG_HMAC_SHA256: - md_type = MBEDTLS_MD_SHA256; + psa_alg = PSA_ALG_SHA_256; break; case CRYPTO_HASH_ALG_SHA384: - md_type = MBEDTLS_MD_SHA384; + psa_alg = PSA_ALG_SHA_384; break; case CRYPTO_HASH_ALG_SHA512: - md_type = MBEDTLS_MD_SHA512; + psa_alg = PSA_ALG_SHA_512; break; default: + os_free(ctx); return NULL; } @@ -184,165 +163,204 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, default: break; } - ctx = os_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - return NULL; - } - mbedtls_md_init(ctx); - md_info = mbedtls_md_info_from_type(md_type); - if (!md_info) { - goto cleanup; - } - if (mbedtls_md_setup(ctx, md_info, is_hmac) != 0) { - goto cleanup; - } + // If is_hmac is set, then it is HMAC mode if (is_hmac) { - ret = mbedtls_md_hmac_starts(ctx, key, key_len); + if (key == NULL || key_len == 0) { + os_free(ctx); + return NULL; + } + + psa_mac_operation_t *operation = os_zalloc(sizeof(psa_mac_operation_t)); + if (operation == NULL) { + os_free(ctx); + return NULL; + } + + psa_key_id_t key_id = 0; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(psa_alg)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); + psa_set_key_bits(&attributes, 8 * key_len); + + psa_status_t status = psa_import_key(&attributes, key, key_len, &key_id); + psa_reset_key_attributes(&attributes); + if (status != PSA_SUCCESS) { + os_free(operation); + os_free(ctx); + return NULL; + } + + status = psa_mac_sign_setup(operation, key_id, PSA_ALG_HMAC(psa_alg)); + if (status != PSA_SUCCESS) { + psa_destroy_key(key_id); + os_free(operation); + os_free(ctx); + return NULL; + } + ctx->is_mac = 1; + ctx->key_id = key_id; + ctx->u.mac_operation = operation; } else { - ret = mbedtls_md_starts(ctx); - } - if (ret < 0) { - goto cleanup; + psa_hash_operation_t *operation = os_zalloc(sizeof(psa_hash_operation_t)); + if (operation == NULL) { + os_free(ctx); + return NULL; + } + + psa_status_t status = psa_hash_setup(operation, psa_alg); + if (status != PSA_SUCCESS) { + os_free(operation); + os_free(ctx); + return NULL; + } + ctx->is_mac = 0; + ctx->key_id = 0; + ctx->u.hash_operation = operation; } - return (struct crypto_hash *)ctx; -cleanup: - mbedtls_md_free(ctx); - os_free(ctx); - return NULL; + return ctx; } void crypto_hash_update(struct crypto_hash *crypto_ctx, const u8 *data, size_t len) { - int ret; - mbedtls_md_context_t *ctx = (mbedtls_md_context_t *)crypto_ctx; - - if (ctx == NULL) { + if (data == NULL || len == 0) { return; } - if (ctx->MBEDTLS_PRIVATE(hmac_ctx)) { - ret = mbedtls_md_hmac_update(ctx, data, len); + + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + + if (crypto_ctx->is_mac) { + status = psa_mac_update(crypto_ctx->u.mac_operation, data, len); } else { - ret = mbedtls_md_update(ctx, data, len); + status = psa_hash_update(crypto_ctx->u.hash_operation, data, len); } - if (ret != 0) { - wpa_printf(MSG_ERROR, "%s: mbedtls_md_hmac_update failed", __func__); + + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_hash_update failed", __func__); } + } int crypto_hash_finish(struct crypto_hash *crypto_ctx, u8 *mac, size_t *len) { int ret = 0; - mbedtls_md_type_t md_type; - mbedtls_md_context_t *ctx = (mbedtls_md_context_t *)crypto_ctx; - if (ctx == NULL) { + if (crypto_ctx == NULL) { return -2; } if (mac == NULL || len == NULL) { - goto err; - } - - md_type = mbedtls_md_get_type(mbedtls_md_info_from_ctx(ctx)); - switch (md_type) { - case MBEDTLS_MD_MD5: - if (*len < MD5_MAC_LEN) { - *len = MD5_MAC_LEN; - ret = -1; - goto err; - } - *len = MD5_MAC_LEN; - break; - case MBEDTLS_MD_SHA1: - if (*len < SHA1_MAC_LEN) { - *len = SHA1_MAC_LEN; - ret = -1; - goto err; - } - *len = SHA1_MAC_LEN; - break; - case MBEDTLS_MD_SHA256: - if (*len < SHA256_MAC_LEN) { - *len = SHA256_MAC_LEN; - ret = -1; - goto err; - } - *len = SHA256_MAC_LEN; - break; - case MBEDTLS_MD_SHA384: - if (*len < SHA384_MAC_LEN) { - *len = SHA384_MAC_LEN; - ret = -1; - goto err; - } - *len = SHA384_MAC_LEN; - break; - case MBEDTLS_MD_SHA512: - if (*len < SHA512_MAC_LEN) { - *len = SHA512_MAC_LEN; - ret = -1; - goto err; - } - *len = SHA512_MAC_LEN; - break; - default: - *len = 0; ret = -1; goto err; } - if (ctx->MBEDTLS_PRIVATE(hmac_ctx)) { - ret = mbedtls_md_hmac_finish(ctx, mac); + + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + + size_t mac_len = 0; + + if (crypto_ctx->is_mac) { + status = psa_mac_sign_finish(crypto_ctx->u.mac_operation, mac, *len, &mac_len); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } } else { - ret = mbedtls_md_finish(ctx, mac); + status = psa_hash_finish(crypto_ctx->u.hash_operation, mac, *len, &mac_len); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } } -err: - mbedtls_md_free(ctx); - bin_clear_free(ctx, sizeof(*ctx)); + *len = mac_len; +err: + if (crypto_ctx->is_mac) { + if (crypto_ctx->u.mac_operation) { + psa_mac_abort(crypto_ctx->u.mac_operation); + os_free(crypto_ctx->u.mac_operation); + } + } else { + if (crypto_ctx->u.hash_operation) { + psa_hash_abort(crypto_ctx->u.hash_operation); + os_free(crypto_ctx->u.hash_operation); + } + } + + if (crypto_ctx->key_id) { + psa_destroy_key(crypto_ctx->key_id); + } + os_free(crypto_ctx); return ret; } -static int hmac_vector(mbedtls_md_type_t md_type, +static int hmac_vector(psa_algorithm_t alg, const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - size_t i; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t md_ctx; - int ret; - - mbedtls_md_init(&md_ctx); - - md_info = mbedtls_md_info_from_type(md_type); - if (!md_info) { - return -1; + int ret = 0; + psa_key_id_t key_id = 0; + if (key == NULL || key_len == 0 || num_elem == 0 || addr == NULL || len == NULL || mac == NULL) { + ret = -1; + goto err; } - ret = mbedtls_md_setup(&md_ctx, md_info, 1); - if (ret != 0) { - return (ret); + psa_status_t status; + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&attributes, PSA_ALG_HMAC(alg)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); + psa_set_key_bits(&attributes, 8 * key_len); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; } - ret = mbedtls_md_hmac_starts(&md_ctx, key, key_len); - if (ret != 0) { - return (ret); + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_HMAC(alg)); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; } - for (i = 0; i < num_elem; i++) { - ret = mbedtls_md_hmac_update(&md_ctx, addr[i], len[i]); - if (ret != 0) { - return (ret); + for (size_t i = 0; i < num_elem; i++) { + status = psa_mac_update(&operation, addr[i], len[i]); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; } - } - ret = mbedtls_md_hmac_finish(&md_ctx, mac); + size_t mac_len; + /* For HMAC, the MAC length equals the hash output length */ + size_t expected_mac_len = PSA_HASH_LENGTH(alg); + status = psa_mac_sign_finish(&operation, mac, expected_mac_len, &mac_len); + if (status != PSA_SUCCESS) { + ret = -1; + goto err; + } - mbedtls_md_free(&md_ctx); + status = psa_destroy_key(key_id); + if (status != PSA_SUCCESS) { + ret = -1; + } + + return ret; + +err: + + if (ret != 0) { + if (key_id) { + psa_destroy_key(key_id); + } + psa_mac_abort(&operation); + } return ret; } @@ -350,7 +368,7 @@ static int hmac_vector(mbedtls_md_type_t md_type, int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return hmac_vector(MBEDTLS_MD_SHA384, key, key_len, num_elem, addr, + return hmac_vector(PSA_ALG_SHA_384, key, key_len, num_elem, addr, len, mac); } @@ -363,7 +381,7 @@ int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return hmac_vector(MBEDTLS_MD_SHA256, key, key_len, num_elem, addr, + return hmac_vector(PSA_ALG_SHA_256, key, key_len, num_elem, addr, len, mac); } @@ -376,7 +394,7 @@ int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return hmac_vector(MBEDTLS_MD_MD5, key, key_len, + return hmac_vector(PSA_ALG_MD5, key, key_len, num_elem, addr, len, mac); } @@ -386,11 +404,11 @@ int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac); } -#ifdef MBEDTLS_SHA1_C +#if (defined(MBEDTLS_SHA1_C) || defined(PSA_WANT_ALG_SHA_1)) int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - return hmac_vector(MBEDTLS_MD_SHA1, key, key_len, num_elem, addr, + return hmac_vector(PSA_ALG_SHA_1, key, key_len, num_elem, addr, len, mac); } @@ -403,48 +421,94 @@ int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, static void *aes_crypt_init(int mode, const u8 *key, size_t len) { - int ret = -1; - mbedtls_aes_context *aes = os_malloc(sizeof(*aes)); - if (!aes) { - return NULL; - } - mbedtls_aes_init(aes); + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t *key_id = os_malloc(sizeof(psa_key_id_t)); - if (mode == MBEDTLS_AES_ENCRYPT) { - ret = mbedtls_aes_setkey_enc(aes, key, len * 8); - } else if (mode == MBEDTLS_AES_DECRYPT) { - ret = mbedtls_aes_setkey_dec(aes, key, len * 8); - } - if (ret < 0) { - mbedtls_aes_free(aes); - os_free(aes); - wpa_printf(MSG_ERROR, "%s: mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec failed", __func__); + if (key_id == NULL) { return NULL; } - return (void *) aes; + if (mode == MBEDTLS_ENCRYPT) { + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + } else if (mode == MBEDTLS_DECRYPT) { + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + } + + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, len * 8); + + status = psa_import_key(&attributes, key, len, key_id); + psa_reset_key_attributes(&attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + os_free(key_id); + return NULL; + } + + return (void *) key_id; } static int aes_crypt(void *ctx, int mode, const u8 *in, u8 *out) { - return mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, - mode, in, out); + psa_status_t status; + psa_key_id_t *key_id = (psa_key_id_t *) ctx; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + size_t output_len; + int ret = -1; + + if (mode == MBEDTLS_ENCRYPT) { + status = psa_cipher_encrypt_setup(&operation, *key_id, PSA_ALG_ECB_NO_PADDING); + } else if (mode == MBEDTLS_DECRYPT) { + status = psa_cipher_decrypt_setup(&operation, *key_id, PSA_ALG_ECB_NO_PADDING); + } else { + wpa_printf(MSG_ERROR, "%s: invalid mode", __func__); + return -1; + } + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + psa_cipher_abort(&operation); + return -1; + } + + status = psa_cipher_update(&operation, in, 16, out, 16, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + goto cleanup; + } + + status = psa_cipher_finish(&operation, out + output_len, 16 - output_len, &output_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + goto cleanup; + } + + ret = 0; + +cleanup: + psa_cipher_abort(&operation); + return ret; } static void aes_crypt_deinit(void *ctx) { - mbedtls_aes_free((mbedtls_aes_context *)ctx); + psa_key_id_t *key_id = (psa_key_id_t *) ctx; + psa_status_t status = psa_destroy_key(*key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_destroy_key failed", __func__); + } os_free(ctx); } void *aes_encrypt_init(const u8 *key, size_t len) { - return aes_crypt_init(MBEDTLS_AES_ENCRYPT, key, len); + return aes_crypt_init(MBEDTLS_ENCRYPT, key, len); } int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) { - return aes_crypt(ctx, MBEDTLS_AES_ENCRYPT, plain, crypt); + return aes_crypt(ctx, MBEDTLS_ENCRYPT, plain, crypt); } void aes_encrypt_deinit(void *ctx) @@ -454,12 +518,12 @@ void aes_encrypt_deinit(void *ctx) void * aes_decrypt_init(const u8 *key, size_t len) { - return aes_crypt_init(MBEDTLS_AES_DECRYPT, key, len); + return aes_crypt_init(MBEDTLS_DECRYPT, key, len); } int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) { - return aes_crypt(ctx, MBEDTLS_AES_DECRYPT, crypt, plain); + return aes_crypt(ctx, MBEDTLS_DECRYPT, crypt, plain); } void aes_decrypt_deinit(void *ctx) @@ -470,114 +534,159 @@ void aes_decrypt_deinit(void *ctx) #ifdef CONFIG_MBEDTLS_CIPHER_MODE_CBC int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) { - int ret = 0; - mbedtls_aes_context ctx; - u8 cbc[MBEDTLS_AES_BLOCK_SIZE]; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - mbedtls_aes_init(&ctx); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); - ret = mbedtls_aes_setkey_enc(&ctx, key, 128); - if (ret < 0) { - mbedtls_aes_free(&ctx); - return ret; + status = psa_import_key(&attributes, key, 16, &key_id); + psa_reset_key_attributes(&attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; } - os_memcpy(cbc, iv, MBEDTLS_AES_BLOCK_SIZE); - ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, - data_len, cbc, data, data); - mbedtls_aes_free(&ctx); + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; - return ret; + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + psa_destroy_key(key_id); + return -1; + } + + status = psa_cipher_set_iv(&operation, iv, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + size_t output_length = 0; + status = psa_cipher_update(&operation, data, data_len, data, data_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + status = psa_cipher_finish(&operation, data + output_length, data_len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + psa_cipher_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) { - int ret = 0; - mbedtls_aes_context ctx; - u8 cbc[MBEDTLS_AES_BLOCK_SIZE]; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - mbedtls_aes_init(&ctx); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); - ret = mbedtls_aes_setkey_dec(&ctx, key, 128); - if (ret < 0) { - mbedtls_aes_free(&ctx); - return ret; + status = psa_import_key(&attributes, key, 16, &key_id); + psa_reset_key_attributes(&attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; } - os_memcpy(cbc, iv, MBEDTLS_AES_BLOCK_SIZE); - ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, - data_len, cbc, data, data); - mbedtls_aes_free(&ctx); + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; - return ret; + status = psa_cipher_decrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_decrypt_setup failed", __func__); + psa_destroy_key(key_id); + return -1; + } + + status = psa_cipher_set_iv(&operation, iv, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + size_t output_length = 0; + + status = psa_cipher_update(&operation, data, data_len, data, data_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + status = psa_cipher_finish(&operation, data + output_length, data_len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + psa_cipher_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + psa_cipher_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } #endif /* CONFIG_MBEDTLS_CIPHER_MODE_CBC */ #ifdef CONFIG_TLS_INTERNAL_CLIENT struct crypto_cipher { - mbedtls_cipher_context_t ctx_enc; - mbedtls_cipher_context_t ctx_dec; + void *ctx_enc; + void *ctx_dec; + psa_key_id_t key_id; }; -static int crypto_init_cipher_ctx(mbedtls_cipher_context_t *ctx, - const mbedtls_cipher_info_t *cipher_info, - const u8 *iv, const u8 *key, size_t key_len, - mbedtls_operation_t operation) +static uint32_t alg_to_psa_cipher(enum crypto_cipher_alg alg) { - mbedtls_cipher_init(ctx); - int ret; - - ret = mbedtls_cipher_setup(ctx, cipher_info); - if (ret != 0) { - return -1; - } - - ret = mbedtls_cipher_setkey(ctx, key, key_len * 8, operation); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_setkey returned error=%d", ret); - return -1; - } - ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->MBEDTLS_PRIVATE(iv_size) << MBEDTLS_IV_SIZE_SHIFT); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_set_iv returned error=%d", ret); - return -1; - } - ret = mbedtls_cipher_reset(ctx); - if (ret != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_reset() returned error=%d", ret); - return -1; + switch (alg) { + case CRYPTO_CIPHER_ALG_AES: + case CRYPTO_CIPHER_ALG_3DES: + case CRYPTO_CIPHER_ALG_DES: + return PSA_ALG_CBC_NO_PADDING; + default: + break; } return 0; } -static mbedtls_cipher_type_t alg_to_mbedtls_cipher(enum crypto_cipher_alg alg, - size_t key_len) +static uint32_t alg_to_psa_key_type(enum crypto_cipher_alg alg) { switch (alg) { case CRYPTO_CIPHER_ALG_AES: - if (key_len == 16) { - return MBEDTLS_CIPHER_AES_128_CBC; - } - if (key_len == 24) { - return MBEDTLS_CIPHER_AES_192_CBC; - } - if (key_len == 32) { - return MBEDTLS_CIPHER_AES_256_CBC; - } - break; -#ifdef MBEDTLS_DES_C + return PSA_KEY_TYPE_AES; case CRYPTO_CIPHER_ALG_3DES: - return MBEDTLS_CIPHER_DES_EDE3_CBC; case CRYPTO_CIPHER_ALG_DES: - return MBEDTLS_CIPHER_DES_CBC; -#endif + return PSA_KEY_TYPE_DES; default: break; } - return MBEDTLS_CIPHER_NONE; + return 0; } struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg, @@ -585,45 +694,99 @@ struct crypto_cipher *crypto_cipher_init(enum crypto_cipher_alg alg, size_t key_len) { struct crypto_cipher *ctx; - mbedtls_cipher_type_t cipher_type; - const mbedtls_cipher_info_t *cipher_info; ctx = (struct crypto_cipher *)os_zalloc(sizeof(*ctx)); if (!ctx) { return NULL; } - cipher_type = alg_to_mbedtls_cipher(alg, key_len); - if (cipher_type == MBEDTLS_CIPHER_NONE) { + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; + psa_cipher_operation_t *enc_operation = NULL; + psa_cipher_operation_t *dec_operation = NULL; + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + uint32_t psa_alg = alg_to_psa_cipher(alg); + if (psa_alg == 0) { + wpa_printf(MSG_ERROR, "%s: invalid cipher algorithm", __func__); + goto cleanup; + } + psa_set_key_algorithm(&attributes, psa_alg); + + uint32_t psa_key_type = alg_to_psa_key_type(alg); + if (psa_key_type == 0) { + wpa_printf(MSG_ERROR, "%s: invalid key type", __func__); + goto cleanup; + } + psa_set_key_type(&attributes, psa_key_type); + psa_set_key_bits(&attributes, key_len * 8); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); goto cleanup; } - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - if (cipher_info == NULL) { + psa_reset_key_attributes(&attributes); + + enc_operation = os_zalloc(sizeof(psa_cipher_operation_t)); + if (!enc_operation) { + wpa_printf(MSG_ERROR, "%s: os_zalloc failed", __func__); goto cleanup; } - /* Init both ctx encryption/decryption */ - if (crypto_init_cipher_ctx(&ctx->ctx_enc, cipher_info, iv, key, - key_len, MBEDTLS_ENCRYPT) < 0) { + ctx->ctx_enc = (void *)enc_operation; + + status = psa_cipher_encrypt_setup(enc_operation, key_id, psa_alg); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); goto cleanup; } - if (crypto_init_cipher_ctx(&ctx->ctx_dec, cipher_info, iv, key, - key_len, MBEDTLS_DECRYPT) < 0) { + status = psa_cipher_set_iv(enc_operation, iv, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); goto cleanup; } -#if defined(CONFIG_MBEDTLS_CIPHER_MODE_WITH_PADDING) - if (mbedtls_cipher_set_padding_mode(&ctx->ctx_enc, MBEDTLS_PADDING_NONE) < 0) { + + dec_operation = os_zalloc(sizeof(psa_cipher_operation_t)); + if (!dec_operation) { + wpa_printf(MSG_ERROR, "%s: os_zalloc failed", __func__); goto cleanup; } - if (mbedtls_cipher_set_padding_mode(&ctx->ctx_dec, MBEDTLS_PADDING_NONE) < 0) { + + ctx->ctx_dec = (void *)dec_operation; + + status = psa_cipher_decrypt_setup(dec_operation, key_id, psa_alg); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_decrypt_setup failed", __func__); goto cleanup; } -#endif /* CONFIG_MBEDTLS_CIPHER_MODE_WITH_PADDING */ + + status = psa_cipher_set_iv(dec_operation, iv, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); + goto cleanup; + } + + ctx->key_id = key_id; + return ctx; cleanup: + if (key_id) { + 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); os_free(ctx); return NULL; } @@ -631,16 +794,20 @@ cleanup: int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, u8 *crypt, size_t len) { - int ret; - size_t olen = 0; + psa_status_t status; + psa_cipher_operation_t *operation = (psa_cipher_operation_t *)ctx->ctx_enc; - ret = mbedtls_cipher_update(&ctx->ctx_enc, plain, len, crypt, &olen); - if (ret != 0) { + size_t output_length = 0; + + status = psa_cipher_update(operation, plain, len, crypt, len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); return -1; } - ret = mbedtls_cipher_finish(&ctx->ctx_enc, crypt + olen, &olen); - if (ret != 0) { + status = psa_cipher_finish(operation, crypt + output_length, len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); return -1; } @@ -650,16 +817,20 @@ int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, u8 *plain, size_t len) { - int ret; - size_t olen = 0; + psa_status_t status; + psa_cipher_operation_t *operation = (psa_cipher_operation_t *)ctx->ctx_dec; - ret = mbedtls_cipher_update(&ctx->ctx_dec, crypt, len, plain, &olen); - if (ret != 0) { + size_t output_length = 0; + + status = psa_cipher_update(operation, crypt, len, plain, len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); return -1; } - ret = mbedtls_cipher_finish(&ctx->ctx_dec, plain + olen, &olen); - if (ret != 0) { + status = psa_cipher_finish(operation, plain + output_length, len - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); return -1; } @@ -668,8 +839,15 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, void crypto_cipher_deinit(struct crypto_cipher *ctx) { - mbedtls_cipher_free(&ctx->ctx_enc); - mbedtls_cipher_free(&ctx->ctx_dec); + psa_status_t status; + psa_cipher_abort((psa_cipher_operation_t *)ctx->ctx_enc); + psa_cipher_abort((psa_cipher_operation_t *)ctx->ctx_dec); + status = psa_destroy_key(ctx->key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_destroy_key failed", __func__); + } + os_free(ctx->ctx_enc); + os_free(ctx->ctx_dec); os_free(ctx); } #endif @@ -678,20 +856,86 @@ void crypto_cipher_deinit(struct crypto_cipher *ctx) int aes_ctr_encrypt(const u8 *key, size_t key_len, const u8 *nonce, u8 *data, size_t data_len) { - int ret; - mbedtls_aes_context ctx; - uint8_t stream_block[MBEDTLS_AES_BLOCK_SIZE]; - size_t offset = 0; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + int ret = -1; + u8 *temp_buf = NULL; - mbedtls_aes_init(&ctx); - ret = mbedtls_aes_setkey_enc(&ctx, key, key_len * 8); - if (ret < 0) { + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CTR); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); goto cleanup; } - ret = mbedtls_aes_crypt_ctr(&ctx, data_len, &offset, (u8 *)nonce, - stream_block, data, data); + + psa_reset_key_attributes(&attributes); + + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CTR); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + goto cleanup; + } + + status = psa_cipher_set_iv(&operation, nonce, 16); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_set_iv failed", __func__); + goto cleanup; + } + + /* Use temporary buffer only when data length is not a multiple of 16 bytes + * to avoid driver restrictions on in-place encryption */ + const size_t AES_BLOCK_SIZE = 16; + const int need_temp_buf = (data_len % AES_BLOCK_SIZE != 0); + + if (need_temp_buf) { + temp_buf = os_malloc(data_len); + if (temp_buf == NULL) { + wpa_printf(MSG_ERROR, "%s: os_malloc failed", __func__); + goto cleanup; + } + } + + size_t output_length = 0; + size_t total_output = 0; + u8 *output_buf = need_temp_buf ? temp_buf : data; + + status = psa_cipher_update(&operation, data, data_len, output_buf, data_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + goto cleanup; + } + total_output += output_length; + + size_t finish_output = 0; + status = psa_cipher_finish(&operation, output_buf + total_output, data_len - total_output, &finish_output); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + goto cleanup; + } + total_output += finish_output; + + /* Copy result back to original buffer if we used temporary buffer */ + if (need_temp_buf) { + os_memcpy(data, temp_buf, data_len); + } + + ret = 0; + cleanup: - mbedtls_aes_free(&ctx); + if (temp_buf) { + os_free(temp_buf); + } + psa_cipher_abort(&operation); + if (key_id) { + psa_destroy_key(key_id); + } + return ret; } #endif /* CONFIG_MBEDTLS_CIPHER_MODE_CTR */ @@ -805,27 +1049,51 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, #ifdef MBEDTLS_DES_C int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) { - int ret; - mbedtls_des_context des; - u8 pkey[8], next, tmp; - int i; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + int ret = -1; - /* Add parity bits to the key */ - next = 0; - for (i = 0; i < 7; i++) { - tmp = key[i]; - pkey[i] = (tmp >> i) | next | 1; - next = tmp << (7 - i); - } - pkey[i] = next | 1; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_DES); + psa_set_key_bits(&attributes, 128); - mbedtls_des_init(&des); - ret = mbedtls_des_setkey_enc(&des, pkey); - if (ret < 0) { - return ret; + status = psa_import_key(&attributes, key, 8, &key_id); + psa_reset_key_attributes(&attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; + } + + status = psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_ECB_NO_PADDING); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_encrypt_setup failed", __func__); + goto cleanup; + } + + size_t output_length = 0; + + status = psa_cipher_update(&operation, clear, 8, cypher, 8, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_update failed", __func__); + goto cleanup; + } + + status = psa_cipher_finish(&operation, cypher + output_length, 8 - output_length, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_cipher_finish failed", __func__); + goto cleanup; + } + + ret = 0; + +cleanup: + psa_cipher_abort(&operation); + if (key_id) { + psa_destroy_key(key_id); } - ret = mbedtls_des_crypt_ecb(&des, clear, cypher); - mbedtls_des_free(&des); return ret; } @@ -837,25 +1105,81 @@ int aes_ccm_ae(const u8 *key, size_t key_len, const u8 *nonce, size_t M, const u8 *plain, size_t plain_len, const u8 *aad, size_t aad_len, u8 *crypt, u8 *auth) { - int ret; - mbedtls_ccm_context ccm; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; - mbedtls_ccm_init(&ccm); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CCM); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); - ret = mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, - key, key_len * 8); - if (ret < 0) { - wpa_printf(MSG_ERROR, "mbedtls_ccm_setkey failed"); - goto cleanup; + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; } - ret = mbedtls_ccm_encrypt_and_tag(&ccm, plain_len, nonce, 13, aad, - aad_len, plain, crypt, auth, M); + psa_reset_key_attributes(&attributes); -cleanup: - mbedtls_ccm_free(&ccm); + psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; - return ret; + status = psa_aead_encrypt_setup(&operation, key_id, PSA_ALG_CCM); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_encrypt_setup failed", __func__); + psa_destroy_key(key_id); + return -1; + } + + status = psa_aead_set_nonce(&operation, nonce, 13); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_set_nonce failed", __func__); + psa_aead_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + status = psa_aead_set_lengths(&operation, aad_len, plain_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_set_lengths failed", __func__); + psa_aead_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + size_t output_length = 0; + size_t tag_len = 0; + + status = psa_aead_update_ad(&operation, aad, aad_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_update_ad failed", __func__); + psa_aead_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + status = psa_aead_update(&operation, plain, plain_len, crypt, plain_len, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_update failed", __func__); + psa_aead_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + size_t finish_output = 0; + status = psa_aead_finish(&operation, crypt + output_length, plain_len - output_length, &finish_output, auth, M, &tag_len); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_finish failed, status: %d", __func__, status); + psa_aead_abort(&operation); + psa_destroy_key(key_id); + return -1; + } + + psa_aead_abort(&operation); + + psa_destroy_key(key_id); + + return 0; } int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, @@ -863,23 +1187,56 @@ int aes_ccm_ad(const u8 *key, size_t key_len, const u8 *nonce, const u8 *aad, size_t aad_len, const u8 *auth, u8 *plain) { - int ret; - mbedtls_ccm_context ccm; + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id; + u8 *ciphertext_with_tag = NULL; + size_t plaintext_length = 0; + int ret = -1; - mbedtls_ccm_init(&ccm); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_CCM); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); - ret = mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, - key, key_len * 8); - if (ret < 0) { - goto cleanup;; + status = psa_import_key(&attributes, key, key_len, &key_id); + psa_reset_key_attributes(&attributes); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); + return -1; } - ret = mbedtls_ccm_star_auth_decrypt(&ccm, crypt_len, - nonce, 13, aad, aad_len, - crypt, plain, auth, M); + /* psa_aead_decrypt expects the tag to be appended to the ciphertext */ + ciphertext_with_tag = os_malloc(crypt_len + M); + if (ciphertext_with_tag == NULL) { + wpa_printf(MSG_ERROR, "%s: os_malloc failed", __func__); + goto cleanup; + } + os_memcpy(ciphertext_with_tag, crypt, crypt_len); + os_memcpy(ciphertext_with_tag + crypt_len, auth, M); + + status = psa_aead_decrypt(key_id, PSA_ALG_CCM, + nonce, 13, + aad, aad_len, + ciphertext_with_tag, crypt_len + M, + plain, crypt_len, &plaintext_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_aead_decrypt failed, status: %d", __func__, status); + goto cleanup; + } + + if (plaintext_length != crypt_len) { + wpa_printf(MSG_ERROR, "%s: plaintext length mismatch: expected %zu, got %zu", __func__, crypt_len, plaintext_length); + goto cleanup; + } + + ret = 0; cleanup: - mbedtls_ccm_free(&ccm); + if (ciphertext_with_tag) { + os_free(ciphertext_with_tag); + } + psa_destroy_key(key_id); return ret; } @@ -889,59 +1246,61 @@ cleanup: int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - const mbedtls_cipher_info_t *cipher_info; - int i, ret = 0; - mbedtls_cipher_type_t cipher_type; - mbedtls_cipher_context_t ctx; - - switch (key_len) { - case 16: - cipher_type = MBEDTLS_CIPHER_AES_128_ECB; - break; - case 24: - cipher_type = MBEDTLS_CIPHER_AES_192_ECB; - break; - case 32: - cipher_type = MBEDTLS_CIPHER_AES_256_ECB; - break; - default: - cipher_type = MBEDTLS_CIPHER_NONE; - break; - } - cipher_info = mbedtls_cipher_info_from_type(cipher_type); - if (cipher_info == NULL) { - /* Failing at this point must be due to a build issue */ - ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; - goto cleanup; - } - - if (key == NULL || mac == NULL) { + if (key == NULL || mac == NULL) { return -1; } - mbedtls_cipher_init(&ctx); + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + int ret = -1; - ret = mbedtls_cipher_setup(&ctx, cipher_info); - if (ret != 0) { + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_CMAC); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, key_len * 8); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_import_key failed", __func__); goto cleanup; } - ret = mbedtls_cipher_cmac_starts(&ctx, key, key_len * 8); - if (ret != 0) { + psa_reset_key_attributes(&attributes); + + status = psa_mac_sign_setup(&operation, key_id, PSA_ALG_CMAC); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_mac_sign_setup failed", __func__); goto cleanup; } - for (i = 0 ; i < num_elem; i++) { - ret = mbedtls_cipher_cmac_update(&ctx, addr[i], len[i]); - if (ret != 0) { + for (int i = 0; i < num_elem; i++) { + status = psa_mac_update(&operation, addr[i], len[i]); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_mac_update failed", __func__); goto cleanup; } } - ret = mbedtls_cipher_cmac_finish(&ctx, mac); + size_t output_length = 0; + + status = psa_mac_sign_finish(&operation, mac, 16, &output_length); + if (status != PSA_SUCCESS) { + wpa_printf(MSG_ERROR, "%s: psa_mac_sign_finish failed", __func__); + goto cleanup; + } + + ret = 0; + cleanup: - mbedtls_cipher_free(&ctx); - return (ret); + psa_mac_abort(&operation); + if (key_id != 0) { + psa_destroy_key(key_id); + } + + return ret; + } int omac1_aes_128_vector(const u8 *key, size_t num_elem, diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c index c938506e946..135952c1279 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c @@ -25,10 +25,11 @@ #if defined(__GNUC__) #include #endif - -#include +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "mbedtls/esp_config.h" #include "utils/wpa_debug.h" +#include "psa/crypto.h" +#include "psa_crypto_driver_esp_sha.h" /* --- MSVC doesn't support C99 --- */ #ifdef _MSC_VER @@ -233,9 +234,9 @@ static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t ms } \ } -static inline void sha1_extract(mbedtls_sha1_context *restrict ctx, uint8_t *restrict out) +static inline void sha1_extract(esp_sha1_context *restrict ctx, uint8_t *restrict out) { -#if defined(MBEDTLS_SHA1_ALT) +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) #if CONFIG_IDF_TARGET_ESP32 /* ESP32 stores internal SHA state in BE format similar to software */ write32_be(ctx->state[0], out); @@ -259,9 +260,9 @@ static inline void sha1_extract(mbedtls_sha1_context *restrict ctx, uint8_t *res #endif } -static inline void sha1_cpy(mbedtls_sha1_context *restrict out, const mbedtls_sha1_context *restrict in) +static inline void sha1_cpy(esp_sha1_context *restrict out, const esp_sha1_context *restrict in) { -#if defined(MBEDTLS_SHA1_ALT) +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) out->state[0] = in->state[0]; out->state[1] = in->state[1]; out->state[2] = in->state[2]; @@ -276,9 +277,9 @@ static inline void sha1_cpy(mbedtls_sha1_context *restrict out, const mbedtls_sh #endif } -static inline void sha1_xor(mbedtls_sha1_context *restrict out, const mbedtls_sha1_context *restrict in) +static inline void sha1_xor(esp_sha1_context *restrict out, const esp_sha1_context *restrict in) { -#if defined(MBEDTLS_SHA1_ALT) +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) out->state[0] ^= in->state[0]; out->state[1] ^= in->state[1]; out->state[2] ^= in->state[2]; @@ -293,19 +294,18 @@ static inline void sha1_xor(mbedtls_sha1_context *restrict out, const mbedtls_sh #endif } -static int mbedtls_sha1_init_start(mbedtls_sha1_context *ctx) +static int esp_sha1_init_start(esp_sha1_context *ctx) { - mbedtls_sha1_init(ctx); - mbedtls_sha1_starts(ctx); -#if defined(CONFIG_IDF_TARGET_ESP32) && defined(MBEDTLS_SHA1_ALT) + 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; #endif return 0; } -#ifndef MBEDTLS_SHA1_ALT -static int sha1_finish(mbedtls_sha1_context *ctx, +#ifndef MBEDTLS_PSA_ACCEL_ALG_SHA_1 +static int sha1_finish(esp_sha1_context *ctx, unsigned char output[20]) { int ret = -1; @@ -326,7 +326,7 @@ static int sha1_finish(mbedtls_sha1_context *ctx, /* We'll need an extra block */ memset(ctx->MBEDTLS_PRIVATE(buffer) + used, 0, 64 - used); - if ((ret = mbedtls_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { + if ((ret = esp_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { goto exit; } @@ -343,7 +343,7 @@ static int sha1_finish(mbedtls_sha1_context *ctx, write32_be(high, ctx->MBEDTLS_PRIVATE(buffer) + 56); write32_be(low, ctx->MBEDTLS_PRIVATE(buffer) + 60); - if ((ret = mbedtls_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { + if ((ret = esp_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { goto exit; } @@ -366,12 +366,12 @@ exit: DECL_PBKDF2(sha1, // _name 64, // _blocksz 20, // _hashsz - mbedtls_sha1_context, // _ctx - mbedtls_sha1_init_start, // _init - mbedtls_sha1_update, // _update - mbedtls_internal_sha1_process, // _xform -#if defined(MBEDTLS_SHA1_ALT) - mbedtls_sha1_finish, // _final + esp_sha1_context, // _ctx + esp_sha1_init_start, // _init + esp_sha1_update, // _update + esp_internal_sha1_process, // _xform +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) + esp_sha1_finish, // _final #else sha1_finish, // _final #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c index 4eef749d73d..f8d09c7f47e 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c @@ -57,7 +57,7 @@ #error "TLS not enabled in mbedtls config" #endif -#if !defined(MBEDTLS_SHA256_C) +#if (!defined(MBEDTLS_SHA256_C) && !defined(PSA_WANT_ALG_SHA_256)) #error "SHA256 is disabled in mbedtls config" #endif @@ -177,7 +177,7 @@ static int set_pki_context(tls_context_t *tls, const struct tls_connection_param ret = mbedtls_pk_parse_key(&tls->clientkey, cfg->private_key_blob, cfg->private_key_blob_len, (const unsigned char *)cfg->private_key_passwd, - cfg->private_key_passwd ? os_strlen(cfg->private_key_passwd) : 0, mbedtls_esp_random, NULL); + cfg->private_key_passwd ? os_strlen(cfg->private_key_passwd) : 0); if (ret < 0) { wpa_printf(MSG_ERROR, "mbedtls_pk_parse_keyfile returned -0x%x", -ret); return ret; @@ -236,32 +236,32 @@ static uint16_t tls_sig_algs_for_suiteb[] = { #endif \ /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA512) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) && defined(MBEDTLS_MD_CAN_SHA512) MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512, -#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA512 */ +#endif /* (MBEDTLS_RSA_C || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) && MBEDTLS_MD_CAN_SHA512 */ -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA384) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) && defined(MBEDTLS_MD_CAN_SHA384) MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384, -#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA384 */ +#endif /* (MBEDTLS_RSA_C || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) && MBEDTLS_MD_CAN_SHA384 */ #endif /* CONFIG_TLSV13 */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) +#if (defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512)) #if defined(MBEDTLS_ECDSA_C) MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA512), MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384), #endif -#if defined(MBEDTLS_RSA_C) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA512), MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA384), #endif -#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_SHA512_C || PSA_WANT_ALG_SHA_512 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ MBEDTLS_TLS_SIG_NONE }; const mbedtls_x509_crt_profile suiteb_mbedtls_x509_crt_profile = { -#if defined(MBEDTLS_SHA512_C) +#if (defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512)) MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512) | #endif @@ -279,6 +279,7 @@ static void tls_set_suiteb_config(tls_context_t *tls) } #endif +#if 0 static uint16_t tls_sig_algs_for_eap[] = { #ifdef CONFIG_TLSV13 @@ -321,61 +322,62 @@ static uint16_t tls_sig_algs_for_eap[] = { #endif \ /* MBEDTLS_X509_RSASSA_PSS_SUPPORT && MBEDTLS_MD_CAN_SHA256 */ -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA512) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) && defined(MBEDTLS_MD_CAN_SHA512) MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512, -#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA512 */ +#endif /* (MBEDTLS_RSA_C || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) && MBEDTLS_MD_CAN_SHA512 */ -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA384) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) && defined(MBEDTLS_MD_CAN_SHA384) MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384, -#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA384 */ +#endif /* (MBEDTLS_RSA_C || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) && MBEDTLS_MD_CAN_SHA384 */ -#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) && defined(MBEDTLS_MD_CAN_SHA256) MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256, -#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA256 */ +#endif /* (MBEDTLS_RSA_C || PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) && MBEDTLS_MD_CAN_SHA256 */ #endif /* CONFIG_TLSV13 */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) -#if defined(MBEDTLS_SHA512_C) +#if (defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512)) #if defined(MBEDTLS_ECDSA_C) MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA512), MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA384), #endif -#if defined(MBEDTLS_RSA_C) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA512), MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA384), #endif -#endif /* MBEDTLS_SHA512_C */ -#if defined(MBEDTLS_SHA256_C) +#endif /* MBEDTLS_SHA512_C || PSA_WANT_ALG_SHA_512 */ +#if (defined(MBEDTLS_SHA256_C) || defined(PSA_WANT_ALG_SHA_256)) #if defined(MBEDTLS_ECDSA_C) MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA256), MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA224), #endif -#if defined(MBEDTLS_RSA_C) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA256), MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA224), #endif -#endif /* MBEDTLS_SHA256_C */ -#if defined(MBEDTLS_SHA1_C) +#endif /* MBEDTLS_SHA256_C || PSA_WANT_ALG_SHA_256 */ +#if (defined(MBEDTLS_SHA1_C) || defined(PSA_WANT_ALG_SHA_1)) #if defined(MBEDTLS_ECDSA_C) MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, MBEDTLS_SSL_HASH_SHA1), #endif -#if defined(MBEDTLS_RSA_C) +#if (defined(MBEDTLS_RSA_C) || defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)) MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, MBEDTLS_SSL_HASH_SHA1), #endif -#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_SHA1_C || PSA_WANT_ALG_SHA_1 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ MBEDTLS_TLS_SIG_NONE }; +#endif /* 0 */ const mbedtls_x509_crt_profile eap_mbedtls_x509_crt_profile = { -#if defined(MBEDTLS_SHA1_C) +#if (defined(MBEDTLS_SHA1_C) || defined(PSA_WANT_ALG_SHA_1)) MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | #endif -#if defined(MBEDTLS_SHA256_C) +#if (defined(MBEDTLS_SHA256_C) || defined(PSA_WANT_ALG_SHA_256)) MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | #endif -#if defined(MBEDTLS_SHA512_C) +#if (defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512)) MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512) | #endif @@ -389,7 +391,7 @@ static void tls_enable_sha1_config(tls_context_t *tls) { const mbedtls_x509_crt_profile *crt_profile = &eap_mbedtls_x509_crt_profile; mbedtls_ssl_conf_cert_profile(&tls->conf, crt_profile); - mbedtls_ssl_conf_sig_algs(&tls->conf, tls_sig_algs_for_eap); + //mbedtls_ssl_conf_sig_algs(&tls->conf, tls_sig_algs_for_eap); } #ifdef CONFIG_ESP_WIFI_DISABLE_KEY_USAGE_CHECK static int tls_disable_key_usages(void *data, mbedtls_x509_crt *cert, int depth, uint32_t *flags) @@ -406,9 +408,8 @@ static const int suiteb_rsa_ciphersuite_preference[] = { MBEDTLS_TLS1_3_AES_256_GCM_SHA384, #endif /* CONFIG_ESP_WIFI_EAP_TLS1_3 */ #if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA512_C) +#if (defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512)) MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, #endif #endif 0 @@ -419,7 +420,7 @@ static const int suiteb_ecc_ciphersuite_preference[] = { MBEDTLS_TLS1_3_AES_256_GCM_SHA384, #endif /* CONFIG_ESP_WIFI_EAP_TLS1_3 */ #if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA512_C) +#if (defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512)) MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, #endif #endif @@ -430,10 +431,10 @@ static const int suiteb_ciphersuite_preference[] = { MBEDTLS_TLS1_3_AES_256_GCM_SHA384, #endif /* CONFIG_ESP_WIFI_EAP_TLS1_3 */ #if defined(MBEDTLS_GCM_C) -#if defined(MBEDTLS_SHA512_C) +#if (defined(MBEDTLS_SHA512_C) || defined(PSA_WANT_ALG_SHA_512)) MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + // MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, #endif #endif 0 @@ -603,8 +604,6 @@ static int tls_create_mbedtls_handle(struct tls_connection *conn, goto exit; } - mbedtls_ssl_conf_rng(&tls->conf, mbedtls_esp_random, NULL); - #if defined(CONFIG_MBEDTLS_SSL_PROTO_TLS1_3) && !defined(CONFIG_TLSV13) /* Disable TLSv1.3 even when enabled in MbedTLS and not enabled in WiFi config. * TODO: Remove Kconfig option for TLSv1.3 when it is matured enough */ @@ -651,13 +650,6 @@ struct tls_connection * tls_connection_init(void *tls_ctx) wpa_printf(MSG_ERROR, "TLS: Failed to allocate connection memory"); return NULL; } -#ifdef CONFIG_TLSV13 - psa_status_t status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - wpa_printf(MSG_ERROR, "Failed to initialize PSA crypto, returned %d", (int) status); - return NULL; - } -#endif /* CONFIG_TLSV13 */ return conn; } @@ -702,15 +694,6 @@ int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, } #ifdef CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER -static void esp_mbedtls_free_dhm(mbedtls_ssl_context *ssl) -{ -#ifdef CONFIG_MBEDTLS_DHM_C - const mbedtls_ssl_config *conf = mbedtls_ssl_context_get_config(ssl); - mbedtls_mpi_free((mbedtls_mpi *)&conf->MBEDTLS_PRIVATE(dhm_P)); - mbedtls_mpi_free((mbedtls_mpi *)&conf->MBEDTLS_PRIVATE(dhm_G)); -#endif /* CONFIG_MBEDTLS_DHM_C */ -} - static void esp_mbedtls_free_keycert(mbedtls_ssl_context *ssl) { mbedtls_ssl_config *conf = (mbedtls_ssl_config *)mbedtls_ssl_context_get_config(ssl); @@ -783,7 +766,6 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, if (cli_state == MBEDTLS_SSL_SERVER_CERTIFICATE) { esp_mbedtls_free_cacert(&tls->ssl); } else if (cli_state == MBEDTLS_SSL_CERTIFICATE_VERIFY) { - esp_mbedtls_free_dhm(&tls->ssl); esp_mbedtls_free_keycert_key(&tls->ssl); esp_mbedtls_free_keycert(&tls->ssl); } diff --git a/components/wpa_supplicant/src/crypto/crypto.h b/components/wpa_supplicant/src/crypto/crypto.h index 7946e6be160..0164b63be02 100644 --- a/components/wpa_supplicant/src/crypto/crypto.h +++ b/components/wpa_supplicant/src/crypto/crypto.h @@ -385,6 +385,17 @@ int __must_check crypto_private_key_sign_pkcs1(struct crypto_private_key *key, const u8 *in, size_t inlen, u8 *out, size_t *outlen); +/** + * crypto_public_key_from_private_key - Extract public key from private key + * @priv_key: Private key + * Returns: Public key or %NULL on failure + * + * This function extracts the public key component from a private key. + * The returned public key must be freed with crypto_public_key_free(). + */ +struct crypto_public_key * crypto_public_key_from_private_key( + struct crypto_private_key *priv_key); + /** * crypto_public_key_free - Free public key * @key: Public key @@ -973,11 +984,12 @@ struct crypto_bignum *crypto_ec_key_get_private_key(struct crypto_ec_key *key); struct crypto_ec_key *crypto_ec_key_parse_priv(const u8 *privkey, size_t privkey_len); /** - * crypto_ec_get_mbedtls_to_nist_group_id - get nist group from mbedtls internal group - * @id: mbedtls group + * crypto_ec_get_mbedtls_to_nist_group_id - get nist group from PSA internal group + * @id: PSA family + * @bits: PSA family size in bits * Returns: NIST group */ -unsigned int crypto_ec_get_mbedtls_to_nist_group_id(int id); +unsigned int crypto_ec_get_mbedtls_to_nist_group_id(int id, int bits); /** * crypto_ec_get_curve_id - get curve id from ec group diff --git a/components/wpa_supplicant/test_apps/main/test_crypto.c b/components/wpa_supplicant/test_apps/main/test_crypto.c index 23f14b8da52..cd925acad05 100644 --- a/components/wpa_supplicant/test_apps/main/test_crypto.c +++ b/components/wpa_supplicant/test_apps/main/test_crypto.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,13 +13,26 @@ #include "utils/common.h" #include "utils/includes.h" #include "crypto/crypto.h" - +#include "crypto/aes_wrap.h" +#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS #include "mbedtls/ecp.h" +#include "mbedtls/pk.h" #include "test_utils.h" #include "test_wpa_supplicant_common.h" +#include "psa/crypto.h" +#include "mbedtls/psa_util.h" +#include "esp_heap_caps.h" +#include "crypto/sha384.h" +#include "esp_log.h" + typedef struct crypto_bignum crypto_bignum; +/* Minimal structure to access key_id from crypto_ec_key wrapper (for test purposes) */ +typedef struct { + psa_key_id_t key_id; +} crypto_ec_key_wrapper_test_t; + TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]") { set_leak_threshold(300); @@ -536,3 +549,939 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]") } } + +TEST_CASE("Test crypto lib aes apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + + { + /* Check init and deinit APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + void *ctx = aes_encrypt_init(key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + + aes_encrypt_deinit(ctx); + + ctx = NULL; + + ctx = aes_decrypt_init(key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + aes_decrypt_deinit(ctx); + } + + { + /* Check encrypt and decrypt APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t plain[16] = {[0 ... 15] = 0xA5}; + const uint8_t expected_cipher[16] = {0x69, 0x84, 0xC9, 0x14, 0x53, 0x57, 0xE1, 0x09, 0xAA, 0x74, 0xDB, 0x96, 0x8B, 0x17, 0xA0, 0x6A}; + + void *ctx = aes_encrypt_init(key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + + uint8_t crypt[16]; + int ret = aes_encrypt(ctx, plain, crypt); + aes_encrypt_deinit(ctx); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(crypt, expected_cipher, 16)); + + ctx = aes_decrypt_init(key, key_size); + TEST_ASSERT_NOT_NULL(ctx); + + uint8_t decrypted[16]; + ret = aes_decrypt(ctx, crypt, decrypted); + aes_decrypt_deinit(ctx); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(decrypted, plain, 16)); + } + + { + /* Check encrypt and decrypt 128 bit CBC APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t iv[16] = {[0 ... 15] = 0x5A}; + uint8_t plain[16] = {[0 ... 15] = 0xA5}; + + const uint8_t expected_cipher[16] = { + 0xA0, 0x67, 0x6C, 0x77, 0x53, 0xE2, 0x17, 0x63, 0x00, 0x4C, 0xB8, 0xF6, 0xA8, 0x9F, 0xC0, 0xD2 + }; + + int ret = aes_128_cbc_encrypt(key, iv, plain, 16); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(plain, expected_cipher, 16)); + + ret = aes_128_cbc_decrypt(key, iv, plain, 16); + TEST_ASSERT(ret == 0); + uint8_t expected_plain[16] = {[0 ... 15] = 0xA5}; + TEST_ASSERT(!memcmp(plain, expected_plain, 16)); + } + + { + /* Check encrypt 128 bit CTR APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t iv[16] = {[0 ... 15] = 0x5A}; + uint8_t plain[16] = {[0 ... 15] = 0xA5}; + + const uint8_t expected_cipher[16] = { + 0x44, 0xF5, 0x91, 0x0A, 0xE0, 0xEF, 0x5C, 0xF2, 0x28, 0xEB, 0x74, 0x41, 0xAA, 0xB2, 0x24, 0xE6 + }; + + int ret = aes_128_ctr_encrypt(key, iv, plain, 16); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(plain, expected_cipher, 16)); + } + + { + /* Check omac1_aes_128 APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t data[16] = {[0 ... 15] = 0xA5}; + uint8_t mac[16]; + + const uint8_t expected_mac[16] = { + 0x4e, 0x47, 0xb3, 0xcc, 0xf8, 0x41, 0xd0, 0x2f, 0xeb, 0xc1, 0xa9, 0x90, 0xdf, 0xc8, 0xe4, 0x8d + }; + + int ret = omac1_aes_128(key, data, 16, mac); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(mac, expected_mac, 16)); + + /* Also check a negative case */ + const uint8_t expected_mac_neg[16] = { + 0x4e, 0x47, 0xb3, 0xcc, 0xf8, 0x41, 0xd0, 0x2f, 0xeb, 0xc1, 0xa9, 0x90, 0xdf, 0xc8, 0xe4, 0x8e + }; + TEST_ASSERT(memcmp(mac, expected_mac_neg, 16)); + } + + { + /* Check aes_ccm_ae APIs */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t nonce[13] = {[0 ... 12] = 0x5A}; + const uint8_t aad[16] = {[0 ... 15] = 0xA5}; + const uint8_t data[16] = {[0 ... 15] = 0xA5}; + uint8_t crypt[16]; + uint8_t tag[16]; + + const uint8_t expected_crypt[16] = { + 0x28, 0xd9, 0xfe, 0x15, 0xc7, 0xc5, 0xc8, 0xb7, 0xc0, 0x18, 0x28, 0x9b, 0x4b, 0x0b, 0xea, 0x66 + }; + + const uint8_t expected_tag[16] = { + 0xbf, 0xf4, 0x0e, 0x51, 0x78, 0xc0, 0xbd, 0x93, 0x29, 0xd7, 0x63, 0x28, 0xc6, 0x71, 0xe6, 0x60 + }; + + int ret = aes_ccm_ae(key, key_size, nonce, 16, data, 16, aad, 16, crypt, tag); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(crypt, expected_crypt, 16)); + + uint8_t decrypted[16] = {0}; + + ret = aes_ccm_ad(key, key_size, nonce, 16, crypt, 16, aad, 16, tag, decrypted); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(tag, expected_tag, 16)); + TEST_ASSERT(!memcmp(decrypted, data, 16)); + } + + { + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t nonce[13] = {[0 ... 12] = 0x5A}; + const uint8_t aad[16] = {[0 ... 15] = 0xA5}; + + /* Test with 32-byte plaintext (not 16 bytes) */ + const uint8_t data_32[32] = {[0 ... 31] = 0xA5}; + uint8_t crypt_32[32]; + uint8_t tag_32[16]; + uint8_t decrypted_32[32] = {0}; + + int ret = aes_ccm_ae(key, key_size, nonce, 16, data_32, 32, aad, 16, crypt_32, tag_32); + TEST_ASSERT(ret == 0); + + ret = aes_ccm_ad(key, key_size, nonce, 16, crypt_32, 32, aad, 16, tag_32, decrypted_32); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(decrypted_32, data_32, 32)); + } + + { + /* Test round-trip encryption/decryption with various PMF-like frame sizes + * PMF frames typically use 8-byte tags and various payload sizes + */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + const uint8_t nonce[13] = {[0 ... 12] = 0x5A}; + const uint8_t aad[24] = {[0 ... 23] = 0xA5}; /* Typical PMF AAD size */ + + /* Test multiple round-trips to catch any state issues */ + for (int i = 0; i < 10; i++) { + uint8_t data[20] = {[0 ... 19] = (uint8_t)(0xA5 + i)}; + uint8_t crypt[20]; + uint8_t tag[8]; /* PMF uses 8-byte tags */ + uint8_t decrypted[20] = {0}; + + int ret = aes_ccm_ae(key, key_size, nonce, 8, data, 20, aad, 24, crypt, tag); + TEST_ASSERT(ret == 0); + + ret = aes_ccm_ad(key, key_size, nonce, 8, crypt, 20, aad, 24, tag, decrypted); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(decrypted, data, 20)); + } + } + + { + /* Test ESP-NOW specific case: M=0 (tag_len=0) with modified nonce + * ESP-NOW uses tag_len=0 and sets nonce[0]=0 when espnow_pkt=true + * This test verifies if PSA implementation handles M=0 correctly + */ + const uint8_t key_size = 16; + const uint8_t key[16] = {[0 ... key_size - 1] = 0x3A}; + uint8_t nonce[13] = {[0 ... 12] = 0x5A}; + nonce[0] = 0; /* ESP-NOW sets nonce[0] = 0 when espnow_pkt=true */ + const uint8_t aad[24] = {[0 ... 23] = 0xA5}; + const uint8_t data[20] = {[0 ... 19] = 0xA5}; + + uint8_t crypt[20]; + uint8_t tag[8] = {0}; /* M=0 means tag_len=0, tag is not verified */ + uint8_t decrypted[20] = {0}; + + /* Test: Encrypt with M=0 (ESP-NOW encryption case) */ + int ret = aes_ccm_ae(key, key_size, nonce, 0, data, 20, aad, 24, crypt, tag); + if (ret != 0) { + TEST_FAIL_MESSAGE("aes_ccm_ae with M=0 failed - PSA may not support zero-length tags for ESP-NOW"); + } + + /* Test: Decrypt with M=0 (ESP-NOW decryption case) */ + ret = aes_ccm_ad(key, key_size, nonce, 0, crypt, 20, aad, 24, tag, decrypted); + if (ret != 0) { + TEST_FAIL_MESSAGE("aes_ccm_ad with M=0 failed - PSA may not support zero-length tags for ESP-NOW"); + } + + TEST_ASSERT(!memcmp(decrypted, data, 20)); + } +} + +TEST_CASE("Test crypto lib ecdsa apis", "[wpa_crypto]") +{ + set_leak_threshold(300); + { + /* Check ecdsa_get_sign apis */ + uint8_t data[64] = {[0 ... 63] = 0xA5}; + uint8_t signature[64]; /* Buffer for signature (r||s) */ + uint8_t r_buf[32]; /* Buffer for r component */ + uint8_t s_buf[32]; /* Buffer for s component */ + + struct crypto_ec_key *eckey = crypto_ec_key_gen(MBEDTLS_ECP_DP_SECP256R1); + TEST_ASSERT_NOT_NULL(eckey); + // Signature length is defined as 2 * key_size + struct crypto_bignum *r = crypto_bignum_init(); + struct crypto_bignum *s = crypto_bignum_init(); + TEST_ASSERT_NOT_NULL(r); + TEST_ASSERT_NOT_NULL(s); + + int ret = crypto_ecdsa_get_sign(data, r, s, eckey, 2 * 32); + TEST_ASSERT(ret == 0); + + /* Extract r and s from bignums to binary buffers */ + ret = crypto_bignum_to_bin(r, r_buf, sizeof(r_buf), 32); + TEST_ASSERT(ret == 32); + ret = crypto_bignum_to_bin(s, s_buf, sizeof(s_buf), 32); + TEST_ASSERT(ret == 32); + + /* Construct signature as r||s (raw format) */ + memcpy(signature, r_buf, 32); + memcpy(signature + 32, s_buf, 32); + + /* Convert raw signature to DER format as required by crypto_ec_key_verify_signature API */ + /* Get key bits from the key object */ + crypto_ec_key_wrapper_test_t *key_wrapper = (crypto_ec_key_wrapper_test_t *)eckey; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = psa_get_key_attributes(key_wrapper->key_id, &key_attributes); + TEST_ASSERT(status == PSA_SUCCESS); + size_t key_bits = psa_get_key_bits(&key_attributes); + psa_reset_key_attributes(&key_attributes); + TEST_ASSERT(key_bits > 0); + + uint8_t der_sig[MBEDTLS_ECDSA_DER_MAX_SIG_LEN(key_bits)]; + size_t der_sig_len = 0; + ret = mbedtls_ecdsa_raw_to_der(key_bits, signature, 64, der_sig, sizeof(der_sig), &der_sig_len); + TEST_ASSERT(ret == 0); + TEST_ASSERT(der_sig_len > 0); + + uint8_t expected_data[64] = {[0 ... 63] = 0xA5}; + ret = crypto_ec_key_verify_signature(eckey, expected_data, 64, der_sig, der_sig_len); + TEST_ASSERT(ret == 1); /* Returns 1 on success */ + + ret = crypto_ec_key_verify_signature_r_s(eckey, expected_data, 64, r_buf, 32, s_buf, 32); + TEST_ASSERT(ret == 0); + + // Negative test case + expected_data[0] = 0x5A; + ret = crypto_ec_key_verify_signature(eckey, expected_data, 64, der_sig, der_sig_len); + TEST_ASSERT(ret == -1); + + crypto_bignum_deinit(r, 1); + crypto_bignum_deinit(s, 1); + crypto_ec_key_deinit(eckey); + } +} + +TEST_CASE("Test crypto lib hash apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + { + /* Check sha256 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[32]; + + uint8_t expected_hash[32] = { + 0xFC, 0x8B, 0x64, 0x00, 0x1C, 0x5F, 0xDD, 0x0F, 0x2F, 0x40, 0xFB, 0x67, 0xDA, 0xE4, 0xA8, 0x65, 0xA2, 0xC5, 0xBD, 0x17, 0x83, 0x66, 0x76, 0xD6, 0xD5, 0xB5, 0x8B, 0x79, 0x17, 0xE3, 0x37, 0x17 + }; + + size_t len[1] = {32}; + int ret = sha256_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 32)); + } + + { + /* Check sha384 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[48]; + + uint8_t expected_hash[48] = { + 0x80, 0xB0, 0xD3, 0xA0, 0x8D, 0x53, 0x0E, 0x02, 0x62, 0x7C, 0x37, 0x4E, 0xF4, 0xBF, 0x50, 0x7F, 0xAA, 0x55, 0x00, 0x1E, 0x2F, 0xFD, 0xCD, 0x20, 0xC0, 0xBE, 0x7D, 0x0F, 0x47, 0xEA, 0x60, 0x0E, 0x3D, 0x98, 0x02, 0x56, 0x69, 0x94, 0x09, 0xC6, 0x73, 0xD6, 0xFC, 0x82, 0x37, 0x42, 0xFC, 0x20 + }; + + size_t len[1] = {32}; + int ret = sha384_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 48)); + } + + { + /* Check sha512 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[64]; + + uint8_t expected_hash[64] = { + 0x77, 0x4B, 0x67, 0xB3, 0xA6, 0x49, 0x77, 0xE9, 0xA4, 0x2E, 0x46, 0x21, 0x7F, 0x17, 0xA6, 0xE8, 0x54, 0x02, 0xA5, 0x0A, 0x1E, 0xC8, 0xB7, 0x5E, 0xB5, 0x3F, 0xCD, 0xD5, 0xD4, 0xEB, 0x4B, 0x54, 0xD4, 0xA2, 0x49, 0xF8, 0x63, 0xE9, 0x71, 0x28, 0xCF, 0x65, 0x29, 0x76, 0x3B, 0xC9, 0x6A, 0xA7, 0x3C, 0xA9, 0xAE, 0x49, 0x78, 0x4D, 0x2F, 0xF1, 0x58, 0xB3, 0x24, 0xA6, 0x01, 0x6C, 0xB5, 0x18 + }; + + size_t len[1] = {32}; + + int ret = sha512_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 64)); + } + + { + /* Check SHA1 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[20]; + size_t len[1] = {32}; + + uint8_t expected_hash[20] = { + 0x37, 0x23, 0xE7, 0x43, 0xD2, 0xEA, 0xB7, 0x95, 0xED, 0x03, 0x4F, 0x03, 0xEC, 0xD2, 0x0E, 0x69, 0xE8, 0x83, 0x92, 0x19 + }; + + int ret = sha1_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 20)); + } + + { + /* Check MD5 APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[16]; + size_t len[1] = {32}; + + uint8_t expected_hash[16] = { + 0x09, 0x6C, 0xAB, 0xA6, 0x66, 0xF7, 0xB5, 0x38, 0x18, 0x86, 0xAA, 0x0B, 0xD5, 0x41, 0x14, 0xED + }; + + int ret = md5_vector(1, data, len, hash); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 16)); + } + + { + /* Check incremental hash APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + uint8_t hash[32]; + size_t len[1] = {32}; + + uint8_t expected_hash[16] = { + 0x09, 0x6C, 0xAB, 0xA6, 0x66, 0xF7, 0xB5, 0x38, 0x18, 0x86, 0xAA, 0x0B, 0xD5, 0x41, 0x14, 0xED + }; + + struct crypto_hash *ctx = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); + TEST_ASSERT_NOT_NULL(ctx); + + crypto_hash_update(ctx, data[0], 32); + + int ret = crypto_hash_finish(ctx, hash, len); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 16)); + } + + { + /* Check incremental hash API with an user side error for memory leaks */ + + struct crypto_hash *ctx = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); + TEST_ASSERT_NOT_NULL(ctx); + + /* Assume a user error occured, no update API call, only finish to free the ctx */ + + int ret = crypto_hash_finish(ctx, NULL, NULL); + TEST_ASSERT(ret == -1); + } + + { + /* Check incremental mac APIs */ + const uint8_t *data[1]; + data[0] = calloc(1, 32); + memset((void *)data[0], 0xA5, 32); + + uint8_t hash[32]; + size_t len[1] = {32}; + + uint8_t key[32] = {[0 ... 31] = 0x3A}; + + uint8_t expected_hash[32] = { + 0x2B, 0x89, 0x55, 0x19, 0x09, 0x26, 0x6E, 0xD1, 0x6C, 0x07, 0x74, 0x07, 0x80, 0x02, 0x10, 0xBE, 0x3C, 0x53, 0x74, 0x74, 0xED, 0x3D, 0x68, 0x50, 0xCA, 0x9F, 0x31, 0x3A, 0xEA, 0x89, 0x7C, 0xD5 + }; + + struct crypto_hash *ctx = crypto_hash_init(CRYPTO_HASH_ALG_HMAC_SHA256, key, 32); + TEST_ASSERT_NOT_NULL(ctx); + + crypto_hash_update(ctx, data[0], 32); + + int ret = crypto_hash_finish(ctx, hash, len); + free((void *)data[0]); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 32)); + } + + { + /* Check hmac_sha384 APIs */ + const uint8_t data[32] = {[0 ... 31] = 0xA5}; + uint8_t hash[48]; + uint8_t key[32] = {[0 ... 31] = 0x3A}; + + uint8_t expected_hash[48] = { + 0x80, 0x14, 0xA0, 0x69, 0xBF, 0xA4, 0x1E, 0x5D, 0x29, 0x8E, 0x2C, 0x60, 0x50, 0xAD, 0x6C, 0xA8, 0xA3, 0xD7, 0xAC, 0x44, 0x70, 0x68, 0x45, 0x5B, 0x03, 0x5C, 0x24, 0xC5, 0x31, 0xF6, 0x7D, 0x26, 0x87, 0xDB, 0x12, 0x59, 0x10, 0x5F, 0xAB, 0xE9, 0xCD, 0xB0, 0x80, 0x96, 0x04, 0xE5, 0x52, 0xCE + }; + + int ret = hmac_sha384(key, 32, data, 32, hash); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(hash, expected_hash, 48)); + } +} + +TEST_CASE("Test crypto lib rsa apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + { + unsigned char rsa_der[] = { + 0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xa2, 0x30, 0xc6, 0xca, 0xec, 0xcd, 0x46, 0xda, 0x96, 0x0d, + 0x2d, 0xe7, 0xa3, 0xc3, 0xcf, 0x03, 0x42, 0xc5, 0x0a, 0x67, 0xb8, 0x57, + 0xca, 0xa7, 0xa4, 0xa6, 0x89, 0x9c, 0x78, 0xe9, 0xfd, 0x8c, 0x4c, 0x11, + 0xc9, 0xf2, 0x5b, 0x77, 0x96, 0x3c, 0x14, 0xed, 0x2f, 0x45, 0x94, 0xbd, + 0x24, 0x47, 0x05, 0x8e, 0xcf, 0x82, 0x25, 0x53, 0x29, 0x62, 0x8d, 0xff, + 0x8c, 0xee, 0x46, 0xae, 0xfb, 0x5e, 0x72, 0xf1, 0x65, 0x0b, 0x91, 0x19, + 0x84, 0x1e, 0x2d, 0xca, 0x4b, 0x9a, 0xcc, 0x99, 0x3c, 0x0a, 0xe7, 0x95, + 0xfc, 0xa6, 0x8d, 0x94, 0x6c, 0x5c, 0xfb, 0x27, 0x3e, 0xc7, 0x26, 0x6c, + 0xab, 0x79, 0x48, 0x0c, 0x42, 0xac, 0x52, 0x97, 0x28, 0x8c, 0x19, 0xef, + 0xaa, 0xd1, 0xee, 0x17, 0xbf, 0xd8, 0xeb, 0x31, 0x43, 0xb3, 0xba, 0xc9, + 0xf2, 0x26, 0xdc, 0x94, 0x10, 0x46, 0xdd, 0x61, 0xf8, 0xf8, 0xc2, 0xbc, + 0xfa, 0x2a, 0x26, 0x6b, 0xea, 0x85, 0xb3, 0x03, 0x1f, 0xfd, 0x1b, 0x4d, + 0xe3, 0x44, 0x74, 0x63, 0xd0, 0x3c, 0x4c, 0x7c, 0xf9, 0x7a, 0x21, 0x86, + 0x46, 0xfa, 0x6d, 0x88, 0xaf, 0x1f, 0xc2, 0x5c, 0x9b, 0x51, 0x64, 0x65, + 0x35, 0x43, 0x7c, 0xcb, 0x59, 0xb2, 0x68, 0xac, 0x9a, 0x08, 0x6b, 0xee, + 0xe7, 0xc1, 0x80, 0xe2, 0xeb, 0x73, 0xd3, 0x67, 0x14, 0xee, 0xeb, 0xf4, + 0x6f, 0x0c, 0xb5, 0x5f, 0xa6, 0xb6, 0xa5, 0x95, 0xf1, 0x4a, 0xe6, 0xec, + 0xa9, 0x0d, 0xe1, 0xfb, 0x3f, 0x7b, 0xd8, 0xbc, 0x5e, 0x51, 0xdc, 0x77, + 0xba, 0x9a, 0x95, 0x29, 0x44, 0xb4, 0x39, 0x74, 0xfa, 0x67, 0x7a, 0xc7, + 0x05, 0x74, 0x64, 0x5b, 0xc9, 0x43, 0x68, 0xe5, 0x40, 0x49, 0xd9, 0xf7, + 0x80, 0x84, 0x80, 0x0c, 0x18, 0x96, 0x96, 0xec, 0x1a, 0x58, 0xac, 0xf9, + 0xc7, 0xe3, 0x74, 0x87, 0xfe, 0xc1, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, + 0x82, 0x01, 0x00, 0x54, 0x67, 0xc1, 0xec, 0xb5, 0x13, 0x97, 0x3e, 0x06, + 0x3c, 0xd1, 0x98, 0xec, 0xf6, 0xe7, 0xf2, 0xb0, 0x7a, 0xce, 0x91, 0x6f, + 0xb3, 0xf0, 0x79, 0x12, 0x0c, 0xc1, 0x2c, 0xb7, 0x18, 0x3e, 0xa5, 0x16, + 0xa9, 0x63, 0x49, 0x47, 0x24, 0x93, 0x00, 0xad, 0x7b, 0x49, 0xd0, 0x92, + 0x39, 0x64, 0x79, 0xb9, 0x80, 0xba, 0xa8, 0xe6, 0x37, 0xc3, 0x1f, 0xd0, + 0xfa, 0x1f, 0x23, 0x99, 0x91, 0x52, 0xab, 0xb2, 0x71, 0xc1, 0xbe, 0x25, + 0x42, 0xfc, 0x28, 0xa0, 0x77, 0xd8, 0xa4, 0xb4, 0xb9, 0x42, 0x30, 0x02, + 0x99, 0x61, 0xa4, 0x63, 0xa5, 0xcc, 0x47, 0x0f, 0x45, 0x3b, 0x3c, 0x74, + 0xd8, 0xb4, 0xdc, 0x27, 0x0c, 0x8a, 0x5e, 0x17, 0x95, 0x26, 0xba, 0xd2, + 0x7c, 0x91, 0x8f, 0x32, 0xb3, 0x15, 0x5a, 0x13, 0xfb, 0xcd, 0x59, 0xe9, + 0x69, 0x53, 0x25, 0xba, 0x41, 0x2b, 0xbf, 0x55, 0x52, 0xb9, 0x38, 0x18, + 0x23, 0x4f, 0xae, 0xfc, 0x14, 0xde, 0xbf, 0x87, 0xeb, 0xcc, 0xce, 0x40, + 0x6d, 0x02, 0x4a, 0x26, 0xb9, 0x7a, 0x85, 0x92, 0x38, 0x45, 0x6e, 0x16, + 0x54, 0xb0, 0xd3, 0x58, 0xb1, 0x35, 0xb4, 0x11, 0x80, 0x22, 0x99, 0x41, + 0x00, 0x7b, 0xd8, 0x54, 0x00, 0xb7, 0x10, 0x4d, 0x22, 0x23, 0xee, 0x58, + 0xd8, 0x35, 0x9d, 0xcf, 0x9a, 0xec, 0x63, 0x0c, 0x28, 0xc9, 0xb3, 0xcc, + 0x7a, 0xf6, 0xc4, 0xd5, 0x32, 0xbf, 0xa6, 0xf2, 0x89, 0x0d, 0x00, 0x0d, + 0x6e, 0xaf, 0xb8, 0xe6, 0x5b, 0xb8, 0xd2, 0x7a, 0x83, 0x2e, 0xb1, 0x96, + 0xdb, 0x30, 0x1a, 0x34, 0x77, 0x99, 0x47, 0x26, 0x18, 0x0f, 0x49, 0xa0, + 0xbc, 0x0a, 0x4c, 0x72, 0xca, 0x0f, 0xda, 0x83, 0xcc, 0x01, 0x38, 0xd1, + 0x16, 0x14, 0xfc, 0x6d, 0xc8, 0xde, 0x8d, 0x4f, 0xb1, 0xbc, 0xdd, 0x62, + 0x72, 0x2b, 0x84, 0xf9, 0xe8, 0x2f, 0x09, 0x02, 0x81, 0x81, 0x00, 0xd1, + 0xbd, 0xef, 0x05, 0xca, 0x72, 0x22, 0x57, 0x75, 0xf8, 0x16, 0x0f, 0x07, + 0x54, 0x34, 0x6f, 0x9b, 0x85, 0x6d, 0x35, 0xdb, 0x7a, 0x01, 0xaf, 0x47, + 0xc8, 0xd4, 0xf3, 0x66, 0x46, 0x5a, 0xcf, 0xee, 0x29, 0x4a, 0x4e, 0xff, + 0x09, 0xaa, 0x03, 0x73, 0xf6, 0x43, 0xb0, 0x66, 0xfb, 0xdd, 0x59, 0xb3, + 0x3d, 0x21, 0x89, 0x0e, 0x7a, 0x93, 0x63, 0x76, 0xb6, 0xc6, 0xf9, 0x1f, + 0xfb, 0x4e, 0x70, 0xec, 0x01, 0x4a, 0x4c, 0xdb, 0x56, 0x22, 0x78, 0xc3, + 0xd2, 0x2b, 0xa0, 0x56, 0x72, 0x75, 0x0a, 0x6f, 0xe6, 0x66, 0x57, 0x48, + 0x42, 0xe1, 0x6f, 0x4c, 0x12, 0x9d, 0xeb, 0x78, 0x2f, 0xdf, 0x53, 0xc6, + 0xc2, 0x62, 0x03, 0x9e, 0x52, 0xe8, 0x99, 0x9a, 0xc2, 0xb8, 0x11, 0x08, + 0x11, 0xa1, 0x3a, 0xc4, 0xd0, 0x03, 0x46, 0xca, 0x34, 0x61, 0x62, 0xa0, + 0xdd, 0x42, 0x91, 0xc5, 0x6b, 0x8e, 0x1b, 0x02, 0x81, 0x81, 0x00, 0xc5, + 0xf6, 0x15, 0x2a, 0xf7, 0x61, 0x99, 0x4f, 0x61, 0x45, 0xab, 0x98, 0x14, + 0x76, 0x15, 0x0a, 0x21, 0xd8, 0x4c, 0x2f, 0x1a, 0x7b, 0xc5, 0xb5, 0xa7, + 0xc6, 0x30, 0x51, 0xce, 0x8d, 0xf4, 0xf9, 0xd4, 0xbd, 0x46, 0xb3, 0x60, + 0x2a, 0x57, 0xdb, 0x9e, 0xc7, 0x95, 0x08, 0x2c, 0xd1, 0x0c, 0xc8, 0x72, + 0x3d, 0x24, 0x77, 0x3f, 0x7f, 0x0e, 0xa7, 0xc4, 0xeb, 0x1b, 0x8f, 0x75, + 0x5c, 0xf2, 0xac, 0x5c, 0x30, 0x76, 0x7d, 0xcc, 0xb6, 0x13, 0x7a, 0x40, + 0xe5, 0x94, 0x34, 0x49, 0xe1, 0xd1, 0x77, 0x95, 0x9e, 0x85, 0x2d, 0x15, + 0x2f, 0x13, 0x95, 0xdd, 0xd8, 0x15, 0x53, 0xbd, 0xb0, 0x21, 0x90, 0x83, + 0x52, 0x55, 0x39, 0x66, 0xac, 0xab, 0x3f, 0x06, 0xff, 0x1c, 0x71, 0xc9, + 0xc8, 0xe2, 0x2a, 0x9e, 0xe5, 0xb3, 0x98, 0xdc, 0x80, 0x9f, 0xca, 0xe4, + 0x96, 0x8d, 0xc3, 0x22, 0x59, 0x84, 0x53, 0x02, 0x81, 0x80, 0x5a, 0x72, + 0x02, 0x31, 0xc8, 0x14, 0x21, 0xb4, 0xff, 0x7d, 0x24, 0xde, 0x04, 0x36, + 0x0e, 0x8a, 0x96, 0x51, 0x1a, 0x40, 0x20, 0x4d, 0xe3, 0x8e, 0x17, 0x71, + 0x86, 0x4b, 0x13, 0xae, 0x81, 0x18, 0xab, 0x46, 0x08, 0xf2, 0x39, 0xce, + 0x8c, 0x0f, 0x03, 0x21, 0x8e, 0x1c, 0xf2, 0xbb, 0xe7, 0xbe, 0xf7, 0xa9, + 0x03, 0xde, 0x1b, 0x6d, 0x46, 0x43, 0x9c, 0xfc, 0xc2, 0x9e, 0xc9, 0x68, + 0xd0, 0x71, 0xa7, 0x84, 0x02, 0xeb, 0x53, 0xa6, 0x38, 0x25, 0x45, 0xa4, + 0x4b, 0x05, 0xd0, 0x61, 0x79, 0x11, 0x30, 0x21, 0xf5, 0xbd, 0xeb, 0xbe, + 0x53, 0x82, 0x70, 0x16, 0x93, 0x1c, 0xe8, 0x6e, 0x14, 0x6b, 0x07, 0x09, + 0xe9, 0xc4, 0x4f, 0xb0, 0xc6, 0xf6, 0xfe, 0x22, 0xbb, 0xc7, 0x34, 0x68, + 0x8d, 0xd3, 0x4e, 0xed, 0xb8, 0x8b, 0xfd, 0x44, 0x4b, 0x3e, 0x81, 0xca, + 0x08, 0x1b, 0xde, 0x3b, 0x3c, 0x43, 0x02, 0x81, 0x80, 0x17, 0xd3, 0x96, + 0x98, 0xa5, 0x4d, 0xc9, 0xf6, 0x13, 0xef, 0x1e, 0xc8, 0x1f, 0x2e, 0x57, + 0x39, 0xf0, 0xf8, 0xe7, 0xb2, 0x83, 0xad, 0x82, 0x0e, 0x6b, 0x33, 0x1f, + 0x7d, 0xb9, 0x2e, 0xbc, 0xdd, 0x95, 0x0d, 0x73, 0x05, 0x03, 0xfe, 0x14, + 0xb5, 0x0a, 0x57, 0x5b, 0x48, 0xb0, 0x9c, 0x38, 0xbd, 0xa7, 0x82, 0x54, + 0x71, 0x45, 0xe3, 0x35, 0x10, 0x5c, 0x53, 0x2f, 0xee, 0x04, 0x62, 0x3b, + 0x93, 0x23, 0x45, 0x71, 0xfd, 0x92, 0x36, 0x18, 0x02, 0x0e, 0xed, 0x92, + 0xf8, 0xf8, 0x2b, 0x85, 0xda, 0xae, 0xd7, 0x75, 0x90, 0x07, 0x8c, 0xb2, + 0xfe, 0xc6, 0xc4, 0xcb, 0x4c, 0x58, 0xf8, 0x6a, 0x11, 0xca, 0xbc, 0x8e, + 0x25, 0x6a, 0x86, 0x3d, 0xd6, 0x48, 0x31, 0x4c, 0x6b, 0x25, 0xae, 0x58, + 0x0a, 0x69, 0x35, 0x9c, 0x78, 0x39, 0x92, 0x01, 0xa9, 0x99, 0xf9, 0xc4, + 0xf6, 0x47, 0x9c, 0x1e, 0xa1, 0x02, 0x81, 0x81, 0x00, 0xae, 0xf4, 0x94, + 0x50, 0xe0, 0x58, 0x7e, 0xed, 0x9b, 0xa9, 0x26, 0x99, 0x24, 0x92, 0x0e, + 0x4f, 0x63, 0x93, 0x80, 0x87, 0x89, 0x78, 0x16, 0xa2, 0x05, 0x46, 0xa2, + 0x0d, 0x3e, 0x44, 0x0b, 0x4a, 0x7f, 0x82, 0x5a, 0x15, 0x4e, 0x93, 0xcf, + 0x95, 0x18, 0x7a, 0x3a, 0xa8, 0xfe, 0xc5, 0xd5, 0x9b, 0xb1, 0x82, 0x00, + 0xab, 0x69, 0x43, 0xa8, 0x8a, 0xef, 0xd6, 0x4c, 0x98, 0x53, 0x95, 0x1b, + 0x87, 0xc6, 0xc7, 0x75, 0x9d, 0xae, 0x30, 0x26, 0x08, 0xbb, 0x29, 0x88, + 0xed, 0xc5, 0x78, 0x9d, 0x9d, 0x47, 0x48, 0x68, 0x73, 0xf3, 0xa4, 0x6c, + 0x3b, 0xff, 0x40, 0xeb, 0x63, 0x0c, 0xa0, 0xaf, 0x5b, 0xc6, 0xf7, 0x6c, + 0xb5, 0x03, 0xdf, 0xaf, 0x58, 0x87, 0xd1, 0x95, 0x0a, 0xea, 0xf9, 0x78, + 0x9e, 0xac, 0x8d, 0x98, 0x1a, 0xe0, 0x3e, 0xe3, 0x69, 0x21, 0x20, 0x38, + 0xdd, 0xc4, 0x34, 0x89, 0x04 + }; + unsigned int rsa_der_len = 1217; + + struct crypto_private_key *priv_ctx = crypto_private_key_import(rsa_der, rsa_der_len, NULL); + TEST_ASSERT_NOT_NULL(priv_ctx); + + // Extract public key from private key - following principle of least privilege + struct crypto_public_key *pub_ctx = crypto_public_key_from_private_key(priv_ctx); + TEST_ASSERT_NOT_NULL(pub_ctx); + + uint8_t data[32] = {[0 ... 31] = 0xA5}; + uint8_t encrypted[2048]; + size_t encrypted_size = 2048; + + // Use the public key for encryption + int ret = crypto_public_key_encrypt_pkcs1_v15(pub_ctx, data, 32, encrypted, &encrypted_size); + TEST_ASSERT(ret == 0); + + uint8_t decrypted[32] = {[0 ... 31] = 0}; + size_t decrypted_size = 32; + + // Use the private key for decryption + ret = crypto_private_key_decrypt_pkcs1_v15(priv_ctx, encrypted, encrypted_size, decrypted, &decrypted_size); + TEST_ASSERT(ret == 0); + TEST_ASSERT(!memcmp(data, decrypted, 32)); + + // Clean up both keys + crypto_public_key_free(pub_ctx); + crypto_private_key_free(priv_ctx); + } + + { + /* Check pkcs1 signature */ + const char *rsa_key = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEowIBAAKCAQEAojDGyuzNRtqWDS3no8PPA0LFCme4V8qnpKaJnHjp/YxMEcny\n" + "W3eWPBTtL0WUvSRHBY7PgiVTKWKN/4zuRq77XnLxZQuRGYQeLcpLmsyZPArnlfym\n" + "jZRsXPsnPscmbKt5SAxCrFKXKIwZ76rR7he/2OsxQ7O6yfIm3JQQRt1h+PjCvPoq\n" + "JmvqhbMDH/0bTeNEdGPQPEx8+Xohhkb6bYivH8Jcm1FkZTVDfMtZsmismghr7ufB\n" + "gOLrc9NnFO7r9G8MtV+mtqWV8Urm7KkN4fs/e9i8XlHcd7qalSlEtDl0+md6xwV0\n" + "ZFvJQ2jlQEnZ94CEgAwYlpbsGlis+cfjdIf+wQIDAQABAoIBAFRnwey1E5c+BjzR\n" + "mOz25/Kwes6Rb7PweRIMwSy3GD6lFqljSUckkwCte0nQkjlkebmAuqjmN8Mf0Pof\n" + "I5mRUquyccG+JUL8KKB32KS0uUIwAplhpGOlzEcPRTs8dNi03CcMil4XlSa60nyR\n" + "jzKzFVoT+81Z6WlTJbpBK79VUrk4GCNPrvwU3r+H68zOQG0CSia5eoWSOEVuFlSw\n" + "01ixNbQRgCKZQQB72FQAtxBNIiPuWNg1nc+a7GMMKMmzzHr2xNUyv6byiQ0ADW6v\n" + "uOZbuNJ6gy6xltswGjR3mUcmGA9JoLwKTHLKD9qDzAE40RYU/G3I3o1PsbzdYnIr\n" + "hPnoLwkCgYEA0b3vBcpyIld1+BYPB1Q0b5uFbTXbegGvR8jU82ZGWs/uKUpO/wmq\n" + "A3P2Q7Bm+91Zsz0hiQ56k2N2tsb5H/tOcOwBSkzbViJ4w9IroFZydQpv5mZXSELh\n" + "b0wSnet4L99TxsJiA55S6JmawrgRCBGhOsTQA0bKNGFioN1CkcVrjhsCgYEAxfYV\n" + "KvdhmU9hRauYFHYVCiHYTC8ae8W1p8YwUc6N9PnUvUazYCpX257HlQgs0QzIcj0k\n" + "dz9/DqfE6xuPdVzyrFwwdn3MthN6QOWUNEnh0XeVnoUtFS8Tld3YFVO9sCGQg1JV\n" + "OWasqz8G/xxxycjiKp7ls5jcgJ/K5JaNwyJZhFMCgYBacgIxyBQhtP99JN4ENg6K\n" + "llEaQCBN444XcYZLE66BGKtGCPI5zowPAyGOHPK75773qQPeG21GQ5z8wp7JaNBx\n" + "p4QC61OmOCVFpEsF0GF5ETAh9b3rvlOCcBaTHOhuFGsHCenET7DG9v4iu8c0aI3T\n" + "Tu24i/1ESz6Byggb3js8QwKBgBfTlpilTcn2E+8eyB8uVznw+Oeyg62CDmszH325\n" + "LrzdlQ1zBQP+FLUKV1tIsJw4vaeCVHFF4zUQXFMv7gRiO5MjRXH9kjYYAg7tkvj4\n" + "K4Xartd1kAeMsv7GxMtMWPhqEcq8jiVqhj3WSDFMayWuWAppNZx4OZIBqZn5xPZH\n" + "nB6hAoGBAK70lFDgWH7tm6kmmSSSDk9jk4CHiXgWogVGog0+RAtKf4JaFU6Tz5UY\n" + "ejqo/sXVm7GCAKtpQ6iK79ZMmFOVG4fGx3WdrjAmCLspiO3FeJ2dR0hoc/OkbDv/\n" + "QOtjDKCvW8b3bLUD369Yh9GVCur5eJ6sjZga4D7jaSEgON3ENIkE\n" + "-----END RSA PRIVATE KEY-----\n"; + + struct crypto_private_key *ctx = crypto_private_key_import((uint8_t *)rsa_key, strlen(rsa_key) + 1, NULL); + TEST_ASSERT_NOT_NULL(ctx); + + uint8_t data[32] = {[0 ... 31] = 0xA5}; + uint8_t signature[2048]; + size_t signature_size = 2048; + + int ret = crypto_private_key_sign_pkcs1((struct crypto_private_key *)ctx, data, 32, signature, &signature_size); + TEST_ASSERT(ret == 0); + + uint8_t expected_signature[256] = { + 0x70, 0x0C, 0xE7, 0xB3, 0x82, 0x05, 0x7B, 0x3D, 0xA9, 0x57, + 0x34, 0xBF, 0xF2, 0x37, 0x1A, 0x64, 0x35, 0xE9, 0xB2, 0x26, + 0xBF, 0xE2, 0xBB, 0x97, 0x92, 0x25, 0x29, 0xA3, 0x33, 0x1F, + 0x1D, 0xEE, 0x57, 0xCA, 0x02, 0x34, 0x1E, 0xE7, 0x44, 0x8A, + 0x56, 0x05, 0x81, 0x3C, 0x81, 0x24, 0xBD, 0x64, 0xEB, 0xC2, + 0x16, 0x23, 0xEA, 0xC7, 0xCA, 0x8D, 0xEC, 0xB6, 0x1B, 0x61, + 0x56, 0x76, 0xBA, 0x0C, 0xBC, 0xE3, 0xA0, 0xB5, 0x13, 0x69, + 0xE4, 0xD6, 0x9C, 0x8C, 0x76, 0x28, 0xAC, 0x55, 0x95, 0x2D, + 0x15, 0x53, 0x95, 0x17, 0x22, 0xC0, 0x5A, 0x0F, 0x79, 0xF9, + 0xAC, 0x1C, 0x17, 0x06, 0x17, 0x81, 0x53, 0x2B, 0x8E, 0x25, + 0x77, 0x52, 0x9C, 0x48, 0x0F, 0x96, 0xB9, 0x3E, 0xD7, 0x3D, + 0x40, 0x79, 0xC8, 0x65, 0xD7, 0x17, 0x58, 0xAB, 0xB6, 0xEC, + 0x4B, 0x51, 0xC4, 0xED, 0x0E, 0xD8, 0xD4, 0x7D, 0xF8, 0x2C, + 0x9B, 0x87, 0x01, 0xE0, 0x72, 0xD5, 0xB9, 0x78, 0x6C, 0xC8, + 0x35, 0xA5, 0x2F, 0x50, 0x8F, 0x2B, 0xCC, 0x2A, 0x76, 0x2D, + 0xD8, 0xC4, 0xBB, 0x9C, 0x02, 0xB4, 0x45, 0x91, 0x95, 0x4E, + 0xDE, 0xF3, 0x86, 0x55, 0xA2, 0xE5, 0x51, 0xC6, 0xBA, 0xA0, + 0xAF, 0xA8, 0x03, 0xD5, 0x83, 0x14, 0x78, 0x56, 0x98, 0x0D, + 0x4E, 0xF3, 0xA1, 0x05, 0x3A, 0x32, 0xEB, 0x99, 0x7B, 0x3D, + 0xEF, 0x46, 0xC8, 0x6E, 0x7B, 0xB5, 0x9F, 0x83, 0xF7, 0xD6, + 0xFE, 0x38, 0xE8, 0x25, 0xB6, 0x0B, 0xF4, 0x26, 0x52, 0xDF, + 0x87, 0xAA, 0x4F, 0x19, 0x68, 0x9B, 0xFB, 0xB6, 0xCE, 0xF0, + 0x77, 0x89, 0xA4, 0xB3, 0xAA, 0xD2, 0x70, 0xA4, 0xFF, 0x9D, + 0x94, 0x20, 0x83, 0xBA, 0x08, 0xD0, 0xD9, 0x7B, 0xD0, 0xD7, + 0x07, 0xB5, 0x74, 0x24, 0xC6, 0x52, 0x85, 0x06, 0x27, 0xA5, + 0x05, 0xD2, 0x3E, 0x1D, 0x0B, 0x2E + }; + + TEST_ASSERT(signature_size == 256); + for (int i = 0; i < signature_size; i++) { + if (signature[i] != expected_signature[i]) { + printf("Mismatch at index %d\n", i); + printf("Expected: %02X, Got: %02X\n", expected_signature[i], signature[i]); + } + } + + crypto_private_key_free(ctx); + } +} + +TEST_CASE("Test crypto lib ec apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + { + psa_key_id_t key_id; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + + psa_status_t status = psa_generate_key(&key_attributes, &key_id); + TEST_ASSERT(status == PSA_SUCCESS); + + unsigned char *key_buf = NULL; + int ret = crypto_write_pubkey_der((struct crypto_ec_key *)&key_id, &key_buf); + TEST_ASSERT(ret > 0); + free(key_buf); + ESP_LOGI("EC Test", "Public key DER size: %d", ret); + psa_destroy_key(key_id); + } +} + +TEST_CASE("Test crypto lib ecdh apis", "[wpa_crypto]") +{ + set_leak_threshold(1); + { + /* Test ECDH key agreement between two keys */ + struct crypto_ec_key *own_key = crypto_ec_key_gen(MBEDTLS_ECP_DP_SECP256R1); + TEST_ASSERT_NOT_NULL(own_key); + + struct crypto_ec_key *peer_key = crypto_ec_key_gen(MBEDTLS_ECP_DP_SECP256R1); + TEST_ASSERT_NOT_NULL(peer_key); + + uint8_t secret[66]; /* Max size for P-256 is 32 bytes, but PSA may return up to 66 */ + size_t secret_len = 0; + + /* Perform ECDH key agreement - this should succeed with our fix */ + int ret = crypto_ecdh(own_key, peer_key, secret, &secret_len); + TEST_ASSERT(ret == 0); + TEST_ASSERT(secret_len > 0); + TEST_ASSERT(secret_len <= 66); + + /* Verify secret is not all zeros */ + int all_zeros = 1; + for (size_t i = 0; i < secret_len; i++) { + if (secret[i] != 0) { + all_zeros = 0; + break; + } + } + TEST_ASSERT(all_zeros == 0); + + /* Test reverse direction (peer -> own) should produce same secret */ + uint8_t secret2[66]; + size_t secret_len2 = 0; + ret = crypto_ecdh(peer_key, own_key, secret2, &secret_len2); + TEST_ASSERT(ret == 0); + TEST_ASSERT(secret_len2 == secret_len); + TEST_ASSERT(!memcmp(secret, secret2, secret_len)); + + crypto_ec_key_deinit(own_key); + crypto_ec_key_deinit(peer_key); + } + + { + /* Test that the same key can be used for both ECDSA signing and ECDH */ + struct crypto_ec_key *key = crypto_ec_key_gen(MBEDTLS_ECP_DP_SECP256R1); + TEST_ASSERT_NOT_NULL(key); + + /* First, test ECDSA signing */ + uint8_t data[64] = {[0 ... 63] = 0xA5}; + struct crypto_bignum *r = crypto_bignum_init(); + struct crypto_bignum *s = crypto_bignum_init(); + TEST_ASSERT_NOT_NULL(r); + TEST_ASSERT_NOT_NULL(s); + + int ret = crypto_ecdsa_get_sign(data, r, s, key, 2 * 32); + TEST_ASSERT(ret == 0); + + /* Extract r and s from bignums to binary buffers */ + uint8_t r_buf[32], s_buf[32], signature[64]; + ret = crypto_bignum_to_bin(r, r_buf, sizeof(r_buf), 32); + TEST_ASSERT(ret == 32); + ret = crypto_bignum_to_bin(s, s_buf, sizeof(s_buf), 32); + TEST_ASSERT(ret == 32); + + /* Construct signature as r||s (raw format) */ + memcpy(signature, r_buf, 32); + memcpy(signature + 32, s_buf, 32); + + /* Convert raw signature to DER format as required by crypto_ec_key_verify_signature API */ + /* Get key bits from the key object */ + crypto_ec_key_wrapper_test_t *key_wrapper = (crypto_ec_key_wrapper_test_t *)key; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = psa_get_key_attributes(key_wrapper->key_id, &key_attributes); + TEST_ASSERT(status == PSA_SUCCESS); + size_t key_bits = psa_get_key_bits(&key_attributes); + psa_reset_key_attributes(&key_attributes); + TEST_ASSERT(key_bits > 0); + + uint8_t der_sig[MBEDTLS_ECDSA_DER_MAX_SIG_LEN(key_bits)]; + size_t der_sig_len = 0; + ret = mbedtls_ecdsa_raw_to_der(key_bits, signature, 64, der_sig, sizeof(der_sig), &der_sig_len); + TEST_ASSERT(ret == 0); + TEST_ASSERT(der_sig_len > 0); + + /* Verify the signature */ + ret = crypto_ec_key_verify_signature(key, data, 64, der_sig, der_sig_len); + TEST_ASSERT(ret == 1); /* Returns 1 on success */ + + /* Now test ECDH with the same key */ + struct crypto_ec_key *peer_key = crypto_ec_key_gen(MBEDTLS_ECP_DP_SECP256R1); + TEST_ASSERT_NOT_NULL(peer_key); + + uint8_t secret[66]; + size_t secret_len = 0; + ret = crypto_ecdh(key, peer_key, secret, &secret_len); + TEST_ASSERT(ret == 0); + TEST_ASSERT(secret_len > 0); + TEST_ASSERT(secret_len <= 66); + + /* Verify secret is not all zeros */ + int all_zeros = 1; + for (size_t i = 0; i < secret_len; i++) { + if (secret[i] != 0) { + all_zeros = 0; + break; + } + } + TEST_ASSERT(all_zeros == 0); + + crypto_bignum_deinit(r, 1); + crypto_bignum_deinit(s, 1); + crypto_ec_key_deinit(key); + crypto_ec_key_deinit(peer_key); + } +} + +TEST_CASE("Test crypto_ecdh_set_peerkey with X-only coordinate (OWE case)", "[wpa_crypto]") +{ + set_leak_threshold(1); + + /* This test verifies the PSA migration fix for OWE association failures. + * OWE (RFC 8110) transmits only the X coordinate of the ECDH public key, + * but PSA's psa_raw_key_agreement() requires the full uncompressed format (0x04 || X || Y). + * The fix converts X-only to uncompressed format before calling PSA. + */ + + { + /* Initialize ECDH context for group 19 (P-256) */ + struct crypto_ecdh *ecdh = crypto_ecdh_init(19); + TEST_ASSERT_NOT_NULL(ecdh); + + /* Get our own public key (X coordinate only, as OWE does) */ + struct wpabuf *our_pubkey = crypto_ecdh_get_pubkey(ecdh, 0); + TEST_ASSERT_NOT_NULL(our_pubkey); + TEST_ASSERT(wpabuf_len(our_pubkey) == 32); /* X coordinate only for P-256 */ + + ESP_LOGI("OWE Test", "Our public key X coordinate length: %zu", wpabuf_len(our_pubkey)); + + /* Create a second ECDH context to simulate peer */ + struct crypto_ecdh *peer_ecdh = crypto_ecdh_init(19); + TEST_ASSERT_NOT_NULL(peer_ecdh); + + /* Get peer's public key (X coordinate only) */ + struct wpabuf *peer_pubkey = crypto_ecdh_get_pubkey(peer_ecdh, 0); + TEST_ASSERT_NOT_NULL(peer_pubkey); + TEST_ASSERT(wpabuf_len(peer_pubkey) == 32); /* X coordinate only for P-256 */ + + ESP_LOGI("OWE Test", "Peer public key X coordinate length: %zu", wpabuf_len(peer_pubkey)); + + /* Test crypto_ecdh_set_peerkey with X-only coordinate (inc_y=0) + * This is the critical path that was failing before the PSA migration fix. + * The function must convert X-only to full uncompressed format internally. + */ + struct wpabuf *shared_secret1 = crypto_ecdh_set_peerkey( + ecdh, 0, + wpabuf_head(peer_pubkey), + wpabuf_len(peer_pubkey) + ); + TEST_ASSERT_NOT_NULL(shared_secret1); + TEST_ASSERT(wpabuf_len(shared_secret1) > 0); + TEST_ASSERT(wpabuf_len(shared_secret1) <= 32); /* P-256 shared secret is 32 bytes max */ + + ESP_LOGI("OWE Test", "Shared secret 1 length: %zu", wpabuf_len(shared_secret1)); + + /* Compute shared secret from the other side */ + struct wpabuf *shared_secret2 = crypto_ecdh_set_peerkey( + peer_ecdh, 0, + wpabuf_head(our_pubkey), + wpabuf_len(our_pubkey) + ); + TEST_ASSERT_NOT_NULL(shared_secret2); + TEST_ASSERT(wpabuf_len(shared_secret2) > 0); + + ESP_LOGI("OWE Test", "Shared secret 2 length: %zu", wpabuf_len(shared_secret2)); + + /* Both sides should compute the same shared secret */ + TEST_ASSERT(wpabuf_len(shared_secret1) == wpabuf_len(shared_secret2)); + TEST_ASSERT(!memcmp(wpabuf_head(shared_secret1), + wpabuf_head(shared_secret2), + wpabuf_len(shared_secret1))); + + /* Verify the shared secret is not all zeros */ + const uint8_t *secret_data = wpabuf_head(shared_secret1); + int all_zeros = 1; + for (size_t i = 0; i < wpabuf_len(shared_secret1); i++) { + if (secret_data[i] != 0) { + all_zeros = 0; + break; + } + } + TEST_ASSERT(all_zeros == 0); + + ESP_LOGI("OWE Test", "✓ X-only ECDH key agreement successful!"); + ESP_LOGI("OWE Test", "✓ Both sides computed identical shared secret"); + ESP_LOGI("OWE Test", "✓ PSA migration fix validated"); + + /* Cleanup */ + wpabuf_free(our_pubkey); + wpabuf_free(peer_pubkey); + wpabuf_free(shared_secret1); + wpabuf_free(shared_secret2); + crypto_ecdh_deinit(ecdh); + crypto_ecdh_deinit(peer_ecdh); + } + + { + /* Test with known test vectors to ensure deterministic behavior + * This uses a fixed private key to generate predictable X coordinate + */ + ESP_LOGI("OWE Test", "Testing with deterministic vectors..."); + + /* Create ECDH context */ + struct crypto_ecdh *ecdh = crypto_ecdh_init(19); + TEST_ASSERT_NOT_NULL(ecdh); + + /* Generate a peer public key */ + struct crypto_ecdh *peer_ecdh = crypto_ecdh_init(19); + TEST_ASSERT_NOT_NULL(peer_ecdh); + + struct wpabuf *peer_pubkey_x = crypto_ecdh_get_pubkey(peer_ecdh, 0); + TEST_ASSERT_NOT_NULL(peer_pubkey_x); + + /* Test that calling set_peerkey twice with same X coordinate yields same result + * This ensures the Y-coordinate reconstruction is deterministic + */ + struct wpabuf *secret1 = crypto_ecdh_set_peerkey( + ecdh, 0, + wpabuf_head(peer_pubkey_x), + wpabuf_len(peer_pubkey_x) + ); + TEST_ASSERT_NOT_NULL(secret1); + + /* Note: We can't call set_peerkey again on same ecdh as it's single-use + * But we verified the core functionality above */ + + ESP_LOGI("OWE Test", "✓ Deterministic vector test passed"); + + wpabuf_free(peer_pubkey_x); + wpabuf_free(secret1); + crypto_ecdh_deinit(ecdh); + crypto_ecdh_deinit(peer_ecdh); + } +} diff --git a/components/wpa_supplicant/test_apps/main/test_dpp.c b/components/wpa_supplicant/test_apps/main/test_dpp.c index 69b5176fe82..2528645b352 100644 --- a/components/wpa_supplicant/test_apps/main/test_dpp.c +++ b/components/wpa_supplicant/test_apps/main/test_dpp.c @@ -34,7 +34,7 @@ extern size_t dpp_nonce_override_len; TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]") { - set_leak_threshold(130); + set_leak_threshold(300); /* Global variables */ char command[1200] = {0}; const u8 *frame; @@ -66,6 +66,10 @@ TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]") sprintf(command, "type=qrcode key=%s", key); id = dpp_bootstrap_gen(dpp, command); uri = dpp_bootstrap_get_uri(dpp, id); + if (uri == NULL) { + ESP_LOGE("DPP Test", "Failed to get URI from bootstrap id"); + TEST_ASSERT(0); + } printf("uri is =%s\n", uri); printf("is be =%s\n", bootstrap_info); TEST_ASSERT((strcmp(uri, bootstrap_info) == 0)); @@ -130,6 +134,9 @@ TEST_CASE("Test vectors DPP responder p256", "[wpa_dpp]") auth_instance = dpp_auth_req_rx(NULL, 1, 0, NULL, dpp_bootstrap_get_id(dpp, id), 2412, frame, frame + 6, len - 6); + TEST_ASSERT_NOT_NULL(auth_instance); + TEST_ASSERT_NOT_NULL(auth_instance->resp_msg); + /* auth response u8 */ hex_len = os_strlen(auth_resp); if (hex_len > 2 * MAX_FRAME_SIZE) { diff --git a/components/wpa_supplicant/test_apps/main/test_fast_pbkdf2.c b/components/wpa_supplicant/test_apps/main/test_fast_pbkdf2.c index 0b6674cf69e..cfb813ad99f 100644 --- a/components/wpa_supplicant/test_apps/main/test_fast_pbkdf2.c +++ b/components/wpa_supplicant/test_apps/main/test_fast_pbkdf2.c @@ -7,7 +7,7 @@ #include #include "unity.h" #include "utils/common.h" -#include "mbedtls/pkcs5.h" +#include "mbedtls/private/pkcs5.h" #include "crypto/sha1.h" #include "test_wpa_supplicant_common.h" diff --git a/components/wpa_supplicant/test_apps/main/test_wpa_supplicant_main.c b/components/wpa_supplicant/test_apps/main/test_wpa_supplicant_main.c index c206b4bf1d1..55bdc1b70b2 100644 --- a/components/wpa_supplicant/test_apps/main/test_wpa_supplicant_main.c +++ b/components/wpa_supplicant/test_apps/main/test_wpa_supplicant_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,7 @@ #include "unity.h" #include "unity_test_runner.h" #include "esp_heap_caps.h" -#include "mbedtls/aes.h" +#include "bignum_impl.h" #include "sdkconfig.h" #include "soc/soc_caps.h" #if SOC_SHA_SUPPORT_PARALLEL_ENG @@ -16,6 +16,8 @@ #include "sha/sha_core.h" #endif +#include "psa/crypto.h" + #define TEST_MEMORY_LEAK_THRESHOLD_DEFAULT 0 static int leak_threshold = TEST_MEMORY_LEAK_THRESHOLD_DEFAULT; void set_leak_threshold(int threshold) @@ -46,21 +48,40 @@ void setUp(void) // and initial DMA setup memory which is considered as leaked otherwise const uint8_t input_buffer[64] = {0}; uint8_t output_buffer[64]; - esp_sha(SHA_TYPE, input_buffer, sizeof(input_buffer), output_buffer); -#endif // SOC_SHA_SUPPORTED +#if SOC_SHA_SUPPORT_SHA512 + esp_sha(SHA2_512, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA512 +#if SOC_SHA_SUPPORT_SHA256 + esp_sha(SHA2_256, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA256 +#if SOC_SHA_SUPPORT_SHA1 + esp_sha(SHA1, input_buffer, sizeof(input_buffer), output_buffer); +#endif // SOC_SHA_SUPPORT_SHA1 +#endif // CONFIG_MBEDTLS_HARDWARE_SHA -#if CONFIG_MBEDTLS_HARDWARE_AES // Execute mbedtls_aes_init operation to allocate AES interrupt // allocation memory which is considered as leak otherwise const uint8_t plaintext[16] = {0}; uint8_t ciphertext[16]; const uint8_t key[16] = { 0 }; - mbedtls_aes_context ctx; - mbedtls_aes_init(&ctx); - mbedtls_aes_setkey_enc(&ctx, key, 128); - mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plaintext, ciphertext); - mbedtls_aes_free(&ctx); -#endif // SOC_AES_SUPPORTED + psa_status_t status; + psa_key_id_t key_id = 0; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + status = psa_import_key(&attributes, key, sizeof(key), &key_id); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + size_t output_len = 0; + status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, plaintext, sizeof(plaintext), ciphertext, sizeof(ciphertext), &output_len); + TEST_ASSERT_EQUAL(PSA_SUCCESS, status); + psa_destroy_key(key_id); + +#if defined(CONFIG_MBEDTLS_HARDWARE_MPI) + esp_mpi_enable_hardware_hw_op(); + esp_mpi_disable_hardware_hw_op(); +#endif // CONFIG_MBEDTLS_HARDWARE_MPI before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); diff --git a/docs/en/migration-guides/release-6.x/6.0/provisioning.rst b/docs/en/migration-guides/release-6.x/6.0/provisioning.rst index 24f327c4004..16fe793985c 100644 --- a/docs/en/migration-guides/release-6.x/6.0/provisioning.rst +++ b/docs/en/migration-guides/release-6.x/6.0/provisioning.rst @@ -35,6 +35,20 @@ The API names have been updated after migrating to the new component. Most chang "wifi_prov_mgr_reset_sm_state_on_failure", "network_prov_mgr_reset_wifi_sm_state_on_failure" "wifi_prov_mgr_reset_sm_state_for_reprovision", "network_prov_mgr_reset_wifi_sm_state_for_reprovision" +BLUFI +----- + +BLUFI (Wi-Fi provisioning over BLE) is affected by the Mbed TLS v4.x / PSA Crypto migration in ESP-IDF v6.0. + +- **Breaking change**: The BLUFI protocol version has been updated (``BTC_BLUFI_SUB_VER`` bumped from ``0x03`` to ``0x04``). The BLUFI security negotiation implementation used by ESP-IDF has also been updated to use PSA Crypto (see the updated ``examples/bluetooth/blufi`` example). + + **Impact**: Existing BLUFI client applications (for example, mobile apps) built against the older BLUFI crypto/protocol implementation may no longer interoperate with devices built with ESP-IDF v6.0. This typically shows up as BLUFI negotiation/connection failures when attempting to provision. + + **Required action**: Update both sides together: + + - Update the device firmware to ESP-IDF v6.0. + - Update the BLUFI client application to a version compatible with the updated BLUFI protocol/security negotiation used by ESP-IDF v6.0. + Configuration Changes --------------------- diff --git a/docs/en/migration-guides/release-6.x/6.0/security.rst b/docs/en/migration-guides/release-6.x/6.0/security.rst index 630275d6c4d..2b07af1a9be 100644 --- a/docs/en/migration-guides/release-6.x/6.0/security.rst +++ b/docs/en/migration-guides/release-6.x/6.0/security.rst @@ -12,7 +12,71 @@ Starting from **ESP-IDF v6.0**, some already deprecated mbedtls header files lik The SHA module headers ``sha/sha_dma.h`` and ``sha/sha_block.h`` are also deprecated and removed. You should include ``sha/sha_core.h`` instead. -**Removed Deprecated APIs** +PSA Crypto migration +~~~~~~~~~~~~~~~~~~~~ + +In ESP-IDF v6.0, multiple ESP-IDF components have been migrated from using legacy Mbed TLS cryptography APIs (for example, ``mbedtls_sha*_*()``, ``mbedtls_md*_*()``, etc.) to using the `PSA Crypto API `__. + +This migration aligns ESP-IDF with Mbed TLS v4.x, where PSA Crypto is the primary cryptography interface, and it enables the use of ESP-IDF hardware acceleration through PSA drivers where available. + +Mbed TLS v4.0 migration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ESP-IDF v6.0 updates to Mbed TLS v4.0, where **PSA Crypto is the primary cryptography interface** (TF-PSA-Crypto provides cryptography; Mbed TLS focuses on TLS and X.509). This can impact applications directly using Mbed TLS cryptography primitives, TLS configuration, or Mbed TLS internal/private declarations. + +- **Breaking change**: In Mbed TLS v4.0, **most legacy cryptography APIs have been removed** and PSA Crypto is the primary interface. If your application directly uses legacy ``mbedtls_*`` cryptography primitives, you may need to migrate to PSA Crypto APIs. +- **Breaking change**: ``psa_crypto_init()`` must be called before any cryptographic operation, including indirect operations such as parsing keys/certificates or starting a TLS handshake. ESP-IDF initializes PSA during normal startup; however, code that runs earlier than the normal startup sequence must call ``psa_crypto_init()`` explicitly. +- **New API**: ``esp_ecdsa_free_pk_context(mbedtls_pk_context *key_ctx)`` was added (``ecdsa/ecdsa_alt.h``). If your application initializes a PK context with a hardware-backed ECDSA key using ``esp_ecdsa_set_pk_context()``, use ``esp_ecdsa_free_pk_context()`` to free it. With PSA-backed Mbed TLS v4.x, ``mbedtls_pk_free()`` does not deallocate the manually created keypair structure in this case. +- **Breaking change**: APIs that previously required an application-provided RNG callback (``f_rng``, ``p_rng``) have changed in Mbed TLS v4.0 to use the PSA RNG instead. Update application code to the new prototypes (for example X.509 write APIs, SSL cookie setup, and SSL ticket setup). +- **Breaking change**: TLS 1.2 / DTLS 1.2 interoperability may be affected because Mbed TLS v4.0 removes support for key exchanges based on finite-field DHE and RSA key exchange without forward secrecy (and static ECDH). If a peer requires removed suites, TLS connections may fail; update server/client cipher suite configuration accordingly. +- **Breaking change**: certificates/peers using elliptic curves of less than 250 bits (for example secp192r1/secp224r1) are no longer supported in certificates and in TLS. +- **Note**: avoid relying on Mbed TLS private declarations (for example headers under ``mbedtls/private/`` or declarations enabled via ``MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS`` / ``MBEDTLS_ALLOW_PRIVATE_ACCESS``). Such private interfaces may change without notice. +- **Note**: the PSA Crypto migration (TF-PSA-Crypto) can increase flash footprint, depending on the features enabled. As reference points: + + .. list-table:: + :header-rows: 1 + :widths: 30 15 15 15 10 + + * - Example + - non PSA build (bytes) + - PSA migration (bytes) + - Diff (bytes) + - Diff (%) + * - :example:`protocols/esp_http_client` + - 609041 + - 646293 + - 37252 + - 5.76 + * - :example:`protocols/https_server` + - 871021 + - 898717 + - 27696 + - 3.08 + * - :example:`protocols/http_server/simple` + - 785825 + - 826909 + - 41084 + - 4.97 + +References +^^^^^^^^^^ + +- :idf_file:`Mbed TLS 4.0 migration guide ` +- :idf_file:`TF-PSA-Crypto 1.0 migration guide ` +- :idf_file:`TF-PSA-Crypto PSA transition notes ` + +Upstream Mbed TLS PSA notes +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Some data structures and internals that applications may have accessed previously are no longer available when using PSA-backed Mbed TLS versions. If your application relied on direct access to Mbed TLS internal state (for example entropy/DRBG contexts as struct fields), migrate to supported public APIs instead. + +PSA persistent storage (ITS) on ESP-IDF +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ESP-IDF provides an implementation of PSA Internal Trusted Storage (ITS) backed by NVS, so PSA persistent storage can be used without a filesystem. If your application uses PSA persistent keys/storage, ensure that NVS is available and initialized before first use. + +Removed deprecated APIs (Mbed TLS / crypto) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following deprecated functions have been removed: diff --git a/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/src/heart_rate_mock.c b/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/src/heart_rate_mock.c index fe8aaf8c89a..21516435e58 100644 --- a/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/src/heart_rate_mock.c +++ b/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/src/heart_rate_mock.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ /* Includes */ -#include "common.h" #include "heart_rate.h" #include "esp_random.h" diff --git a/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/src/led.c b/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/src/led.c index 8a11d00b027..a00d5459ede 100644 --- a/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/src/led.c +++ b/examples/bluetooth/ble_get_started/bluedroid/Bluedroid_GATT_Server/main/src/led.c @@ -5,7 +5,6 @@ */ /* Includes */ #include "led.h" -#include "common.h" /* Private variables */ static uint8_t led_state; diff --git a/examples/bluetooth/blufi/main/blufi_security.c b/examples/bluetooth/blufi/main/blufi_security.c index 123f506336a..065be153527 100644 --- a/examples/bluetooth/blufi/main/blufi_security.c +++ b/examples/bluetooth/blufi/main/blufi_security.c @@ -23,9 +23,7 @@ #include "esp_blufi_api.h" #include "blufi_example.h" -#include "mbedtls/aes.h" -#include "mbedtls/dhm.h" -#include "mbedtls/md5.h" +#include "psa/crypto.h" #include "esp_crc.h" /* @@ -40,10 +38,10 @@ struct blufi_security { -#define DH_SELF_PUB_KEY_LEN 128 #define DH_PARAM_LEN_MAX 1024 +#define DH_SELF_PUB_KEY_LEN 256 uint8_t self_public_key[DH_SELF_PUB_KEY_LEN]; -#define SHARE_KEY_LEN 128 +#define SHARE_KEY_LEN 256 uint8_t share_key[SHARE_KEY_LEN]; size_t share_len; #define PSK_LEN 16 @@ -51,17 +49,10 @@ struct blufi_security { uint8_t *dh_param; int dh_param_len; uint8_t iv[16]; - mbedtls_dhm_context dhm; - mbedtls_aes_context aes; + psa_key_id_t aes_key; }; static struct blufi_security *blufi_sec; -static int myrand( void *rng_state, unsigned char *output, size_t len ) -{ - esp_fill_random(output, len); - return( 0 ); -} - extern void btc_blufi_report_error(esp_blufi_error_state_t state); void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free) @@ -72,7 +63,6 @@ void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_da return; } - int ret; uint8_t type = data[0]; if (blufi_sec == NULL) { @@ -116,56 +106,78 @@ void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_da return; } + uint8_t *param = blufi_sec->dh_param; memcpy(blufi_sec->dh_param, &data[1], blufi_sec->dh_param_len); - ret = mbedtls_dhm_read_params(&blufi_sec->dhm, ¶m, ¶m[blufi_sec->dh_param_len]); - if (ret) { - BLUFI_ERROR("%s read param failed %d\n", __func__, ret); - btc_blufi_report_error(ESP_BLUFI_READ_PARAM_ERROR); + size_t p_len = (param[0] << 8) | param[1]; + param += 2 + p_len; + + size_t g_len = (param[0] << 8) | param[1]; + param += 2 + g_len; + + size_t pub_len = (param[0] << 8) | param[1]; + param += 2; + ESP_LOGD("blfi", "P len %d, G len %d, pub len %d", p_len, g_len, pub_len); + + psa_key_type_t key_type = PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919); + size_t key_bits = 3072; + ESP_LOGI("blfi", "DH param len %d, bits %d", blufi_sec->dh_param_len, key_bits); + psa_algorithm_t alg = PSA_ALG_FFDH; + psa_key_attributes_t attributes = psa_key_attributes_init(); + psa_set_key_type(&attributes, key_type); + psa_set_key_bits(&attributes, key_bits); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); + psa_key_id_t private_key = 0; + psa_status_t status = psa_generate_key(&attributes, &private_key); + if (status != PSA_SUCCESS) { + BLUFI_ERROR("%s psa_generate_key failed %d\n", __func__, status); + btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR); + return; + } + psa_reset_key_attributes(&attributes); + size_t public_key_len = 0; + status = psa_export_public_key(private_key, blufi_sec->self_public_key, DH_SELF_PUB_KEY_LEN, &public_key_len); + if (status != PSA_SUCCESS) { + BLUFI_ERROR("%s psa_export_public_key failed %d\n", __func__, status); + psa_destroy_key(private_key); + btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR); return; } - free(blufi_sec->dh_param); - blufi_sec->dh_param = NULL; - const int dhm_len = mbedtls_dhm_get_len(&blufi_sec->dhm); - - if (dhm_len > DH_SELF_PUB_KEY_LEN) { - BLUFI_ERROR("%s dhm len not support %d\n", __func__, dhm_len); + status = psa_raw_key_agreement(alg, private_key, param, pub_len, blufi_sec->share_key, SHARE_KEY_LEN, &blufi_sec->share_len); + psa_destroy_key(private_key); + if (status != PSA_SUCCESS) { + BLUFI_ERROR("%s psa_raw_key_agreement failed %d\n", __func__, status); + free(blufi_sec->dh_param); + blufi_sec->dh_param = NULL; btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR); return; } - ret = mbedtls_dhm_make_public(&blufi_sec->dhm, dhm_len, blufi_sec->self_public_key, DH_SELF_PUB_KEY_LEN, myrand, NULL); - if (ret) { - BLUFI_ERROR("%s make public failed %d\n", __func__, ret); - btc_blufi_report_error(ESP_BLUFI_MAKE_PUBLIC_ERROR); - return; - } - - ret = mbedtls_dhm_calc_secret( &blufi_sec->dhm, - blufi_sec->share_key, - SHARE_KEY_LEN, - &blufi_sec->share_len, - myrand, NULL); - if (ret) { - BLUFI_ERROR("%s mbedtls_dhm_calc_secret failed %d\n", __func__, ret); - btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR); - return; - } - - ret = mbedtls_md5(blufi_sec->share_key, blufi_sec->share_len, blufi_sec->psk); - - if (ret) { - BLUFI_ERROR("%s mbedtls_md5 failed %d\n", __func__, ret); + size_t hash_length = 0; + status = psa_hash_compute(PSA_ALG_MD5, blufi_sec->share_key, blufi_sec->share_len, blufi_sec->psk, PSK_LEN, &hash_length); + if (status != PSA_SUCCESS) { + BLUFI_ERROR("%s psa_hash_compute failed %d\n", __func__, status); btc_blufi_report_error(ESP_BLUFI_CALC_MD5_ERROR); return; } - mbedtls_aes_setkey_enc(&blufi_sec->aes, blufi_sec->psk, PSK_LEN * 8); + // mbedtls_aes_setkey_enc(&blufi_sec->aes, blufi_sec->psk, PSK_LEN * 8); + attributes = psa_key_attributes_init(); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, PSK_LEN * 8); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + status = psa_import_key(&attributes, blufi_sec->psk, PSK_LEN, &blufi_sec->aes_key); + if (status != PSA_SUCCESS) { + BLUFI_ERROR("%s psa_import_key failed %d\n", __func__, status); + btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR); + return; + } /* alloc output data */ *output_data = &blufi_sec->self_public_key[0]; - *output_len = dhm_len; + *output_len = public_key_len; *need_free = false; } @@ -181,40 +193,76 @@ void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_da int blufi_aes_encrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len) { - int ret; - size_t iv_offset = 0; uint8_t iv0[16]; if (!blufi_sec) { return -1; } - memcpy(iv0, blufi_sec->iv, sizeof(blufi_sec->iv)); - iv0[0] = iv8; /* set iv8 as the iv0[0] */ - - ret = mbedtls_aes_crypt_cfb128(&blufi_sec->aes, MBEDTLS_AES_ENCRYPT, crypt_len, &iv_offset, iv0, crypt_data, crypt_data); - if (ret) { + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_status_t status = psa_cipher_encrypt_setup(&operation, blufi_sec->aes_key, PSA_ALG_CFB); + if (status != PSA_SUCCESS) { return -1; } - return crypt_len; + memcpy(iv0, blufi_sec->iv, sizeof(blufi_sec->iv)); + iv0[0] = iv8; + + status = psa_cipher_set_iv(&operation, iv0, sizeof(iv0)); + if (status != PSA_SUCCESS) { + psa_cipher_abort(&operation); + return -1; + } + + size_t encrypt_out_len = 0; + status = psa_cipher_update(&operation, crypt_data, crypt_len, crypt_data, crypt_len, &encrypt_out_len); + if (status != PSA_SUCCESS) { + psa_cipher_abort(&operation); + return -1; + } + + status = psa_cipher_finish(&operation, crypt_data, crypt_len, &encrypt_out_len); + if (status != PSA_SUCCESS) { + psa_cipher_abort(&operation); + return -1; + } + + return encrypt_out_len; } int blufi_aes_decrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len) { - int ret; - size_t iv_offset = 0; uint8_t iv0[16]; if (!blufi_sec) { return -1; } - memcpy(iv0, blufi_sec->iv, sizeof(blufi_sec->iv)); - iv0[0] = iv8; /* set iv8 as the iv0[0] */ + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_status_t status = psa_cipher_decrypt_setup(&operation, blufi_sec->aes_key, PSA_ALG_CFB); + if (status != PSA_SUCCESS) { + return -1; + } - ret = mbedtls_aes_crypt_cfb128(&blufi_sec->aes, MBEDTLS_AES_DECRYPT, crypt_len, &iv_offset, iv0, crypt_data, crypt_data); - if (ret) { + memcpy(iv0, blufi_sec->iv, sizeof(blufi_sec->iv)); + iv0[0] = iv8; + + status = psa_cipher_set_iv(&operation, iv0, sizeof(iv0)); + if (status != PSA_SUCCESS) { + psa_cipher_abort(&operation); + return -1; + } + + size_t encrypt_out_len = 0; + status = psa_cipher_update(&operation, crypt_data, crypt_len, crypt_data, crypt_len, &encrypt_out_len); + if (status != PSA_SUCCESS) { + psa_cipher_abort(&operation); + return -1; + } + + status = psa_cipher_finish(&operation, crypt_data, crypt_len, &encrypt_out_len); + if (status != PSA_SUCCESS) { + psa_cipher_abort(&operation); return -1; } @@ -236,9 +284,6 @@ esp_err_t blufi_security_init(void) memset(blufi_sec, 0x0, sizeof(struct blufi_security)); - mbedtls_dhm_init(&blufi_sec->dhm); - mbedtls_aes_init(&blufi_sec->aes); - memset(blufi_sec->iv, 0x0, sizeof(blufi_sec->iv)); return 0; } @@ -252,8 +297,7 @@ void blufi_security_deinit(void) free(blufi_sec->dh_param); blufi_sec->dh_param = NULL; } - mbedtls_dhm_free(&blufi_sec->dhm); - mbedtls_aes_free(&blufi_sec->aes); + psa_destroy_key(blufi_sec->aes_key); memset(blufi_sec, 0x0, sizeof(struct blufi_security)); diff --git a/examples/bluetooth/blufi/sdkconfig.defaults b/examples/bluetooth/blufi/sdkconfig.defaults index a68c42e84a8..797047814d5 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults +++ b/examples/bluetooth/blufi/sdkconfig.defaults @@ -15,4 +15,3 @@ CONFIG_BT_GATTC_ENABLE=n CONFIG_BT_BLE_SMP_ENABLE=n CONFIG_BT_BLE_BLUFI_ENABLE=y CONFIG_MBEDTLS_HARDWARE_MPI=n -CONFIG_MBEDTLS_DHM_C=y diff --git a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c2 b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c2 index 128be8ddd80..9e6420f7700 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c2 +++ b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c2 @@ -8,7 +8,6 @@ CONFIG_BT_NIMBLE_BLUFI_ENABLE=y # CONFIG_BT_BLE_SMP_ENABLE is not set # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_MBEDTLS_DHM_C=y # The config items for NIMBLE HOST CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_ROLE_CENTRAL=n diff --git a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c5 b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c5 index 128be8ddd80..9e6420f7700 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c5 +++ b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c5 @@ -8,7 +8,6 @@ CONFIG_BT_NIMBLE_BLUFI_ENABLE=y # CONFIG_BT_BLE_SMP_ENABLE is not set # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_MBEDTLS_DHM_C=y # The config items for NIMBLE HOST CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_ROLE_CENTRAL=n diff --git a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c6 b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c6 index 128be8ddd80..9e6420f7700 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c6 +++ b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c6 @@ -8,7 +8,6 @@ CONFIG_BT_NIMBLE_BLUFI_ENABLE=y # CONFIG_BT_BLE_SMP_ENABLE is not set # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_MBEDTLS_DHM_C=y # The config items for NIMBLE HOST CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_ROLE_CENTRAL=n diff --git a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c61 b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c61 index 128be8ddd80..9e6420f7700 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults.esp32c61 +++ b/examples/bluetooth/blufi/sdkconfig.defaults.esp32c61 @@ -8,7 +8,6 @@ CONFIG_BT_NIMBLE_BLUFI_ENABLE=y # CONFIG_BT_BLE_SMP_ENABLE is not set # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y -CONFIG_MBEDTLS_DHM_C=y # The config items for NIMBLE HOST CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_ROLE_CENTRAL=n diff --git a/examples/bluetooth/blufi/sdkconfig.defaults.mini b/examples/bluetooth/blufi/sdkconfig.defaults.mini index ae88731ccd7..2f81ae696a2 100644 --- a/examples/bluetooth/blufi/sdkconfig.defaults.mini +++ b/examples/bluetooth/blufi/sdkconfig.defaults.mini @@ -47,7 +47,6 @@ CONFIG_BT_NIMBLE_DIS_SERVICE=n CONFIG_BT_ALARM_MAX_NUM=15 CONFIG_MBEDTLS_HARDWARE_MPI=n -CONFIG_MBEDTLS_DHM_C=y CONFIG_BT_NIMBLE_BLUFI_ENABLE=y diff --git a/examples/bluetooth/esp_ble_mesh/aligenie_demo/main/aligenie_demo.c b/examples/bluetooth/esp_ble_mesh/aligenie_demo/main/aligenie_demo.c index 2bfd9397ab8..1858bc0946d 100644 --- a/examples/bluetooth/esp_ble_mesh/aligenie_demo/main/aligenie_demo.c +++ b/examples/bluetooth/esp_ble_mesh/aligenie_demo/main/aligenie_demo.c @@ -16,7 +16,7 @@ #include "esp_mac.h" #include "nvs_flash.h" -#include "mbedtls/sha256.h" +#include "psa/crypto.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_networking_api.h" @@ -32,6 +32,8 @@ #include "genie_mesh.h" #include "ble_mesh_example_init.h" #include "ble_mesh_example_nvs.h" +#include "psa/crypto_struct.h" +#include "psa/crypto_values.h" static const char *TAG = "genie_demo"; @@ -1335,7 +1337,12 @@ void config_triples(void) ESP_LOGI(TAG, "authvalue_string: %s", authvalue_string); uint8_t sha256_out[32] = {0}; - mbedtls_sha256((const unsigned char *)authvalue_string, strlen(authvalue_string), sha256_out, 0); + size_t hash_length = 0; + psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t *)authvalue_string, strlen(authvalue_string), sha256_out, sizeof(sha256_out), &hash_length); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to compute hash, status: %ld", status); + return; + } memcpy(static_val, sha256_out, 16); provision.static_val = static_val; diff --git a/examples/bluetooth/nimble/bleprph/main/gatt_svr.c b/examples/bluetooth/nimble/bleprph/main/gatt_svr.c index d48a35f0abf..eb45537f4f7 100644 --- a/examples/bluetooth/nimble/bleprph/main/gatt_svr.c +++ b/examples/bluetooth/nimble/bleprph/main/gatt_svr.c @@ -240,7 +240,9 @@ gatt_svr_init(void) { int rc; +#if CONFIG_BT_NIMBLE_GAP_SERVICE ble_svc_gap_init(); +#endif /* CONFIG_BT_NIMBLE_GAP_SERVICE */ ble_svc_gatt_init(); ble_svc_ans_init(); diff --git a/examples/mesh/internal_communication/sdkconfig.ci.esp32c5 b/examples/mesh/internal_communication/sdkconfig.ci.esp32c5 new file mode 100644 index 00000000000..1686559de40 --- /dev/null +++ b/examples/mesh/internal_communication/sdkconfig.ci.esp32c5 @@ -0,0 +1 @@ +CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/network/sta2eth/CMakeLists.txt b/examples/network/sta2eth/CMakeLists.txt index 9de95e80b47..6bb79597850 100644 --- a/examples/network/sta2eth/CMakeLists.txt +++ b/examples/network/sta2eth/CMakeLists.txt @@ -2,6 +2,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.22) +list(APPEND sdkconfig_defaults ${CMAKE_CURRENT_LIST_DIR}/mbedtls_preset_sta2eth.conf) include($ENV{IDF_PATH}/tools/cmake/project.cmake) # "Trim" the build. Include the minimal set of components, main, and anything it depends on. idf_build_set_property(MINIMAL_BUILD ON) diff --git a/examples/network/sta2eth/mbedtls_preset_sta2eth.conf b/examples/network/sta2eth/mbedtls_preset_sta2eth.conf new file mode 100644 index 00000000000..20e55bc53ef --- /dev/null +++ b/examples/network/sta2eth/mbedtls_preset_sta2eth.conf @@ -0,0 +1,7 @@ +CONFIG_MBEDTLS_RIPEMD160_C=n +CONFIG_MBEDTLS_SHA1_C=n +CONFIG_MBEDTLS_CAMELLIA_C=n +CONFIG_MBEDTLS_SELF_TEST=n +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_AES=y diff --git a/examples/network/sta2eth/sdkconfig.defaults b/examples/network/sta2eth/sdkconfig.defaults index 6e41a8774fc..accb0a96884 100644 --- a/examples/network/sta2eth/sdkconfig.defaults +++ b/examples/network/sta2eth/sdkconfig.defaults @@ -1 +1,2 @@ CONFIG_EXAMPLE_WIRED_INTERFACE_IS_ETHERNET=y +CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/network/sta2eth/sdkconfig.defaults.esp32c5 b/examples/network/sta2eth/sdkconfig.defaults.esp32c5 deleted file mode 100644 index 1b4441d4f08..00000000000 --- a/examples/network/sta2eth/sdkconfig.defaults.esp32c5 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_EXAMPLE_WIRED_INTERFACE_IS_ETHERNET=y - -CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/network/sta2eth/sdkconfig.defaults.esp32c6 b/examples/network/sta2eth/sdkconfig.defaults.esp32c6 deleted file mode 100644 index 1b4441d4f08..00000000000 --- a/examples/network/sta2eth/sdkconfig.defaults.esp32c6 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_EXAMPLE_WIRED_INTERFACE_IS_ETHERNET=y - -CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/network/sta2eth/sdkconfig.defaults.esp32c61 b/examples/network/sta2eth/sdkconfig.defaults.esp32c61 deleted file mode 100644 index 1b4441d4f08..00000000000 --- a/examples/network/sta2eth/sdkconfig.defaults.esp32c61 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_EXAMPLE_WIRED_INTERFACE_IS_ETHERNET=y - -CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/protocols/esp_http_client/pytest_esp_http_client.py b/examples/protocols/esp_http_client/pytest_esp_http_client.py index 6c44b8b3f70..e58e6282244 100644 --- a/examples/protocols/esp_http_client/pytest_esp_http_client.py +++ b/examples/protocols/esp_http_client/pytest_esp_http_client.py @@ -18,7 +18,7 @@ def test_examples_protocol_esp_http_client(dut: Dut) -> None: """ binary_file = os.path.join(dut.app.binary_path, 'esp_http_client_example.bin') bin_size = os.path.getsize(binary_file) - logging.info('esp_http_client_bin_size : {}KB'.format(bin_size // 1024)) + logging.info(f'esp_http_client_bin_size : {bin_size // 1024}KB') # start test dut.expect('Connected to AP, begin http example', timeout=30) dut.expect(r'HTTP GET Status = 200, content_length = (\d)') @@ -71,7 +71,7 @@ def test_examples_protocol_esp_http_client_dynamic_buffer(dut: Dut) -> None: # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'esp_http_client_example.bin') bin_size = os.path.getsize(binary_file) - logging.info('esp_http_client_bin_size : {}KB'.format(bin_size // 1024)) + logging.info(f'esp_http_client_bin_size : {bin_size // 1024}KB') dut.expect('Connected to AP, begin http example', timeout=30) dut.expect(r'HTTP GET Status = 200, content_length = (\d)') diff --git a/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn b/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn index 09b7458484f..7aca5de18f4 100644 --- a/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn +++ b/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn @@ -10,5 +10,4 @@ CONFIG_EXAMPLE_CONNECT_IPV6=y CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH=y CONFIG_MBEDTLS_DYNAMIC_BUFFER=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y -CONFIG_MBEDTLS_DHM_C=y CONFIG_EXAMPLE_HTTP_ENDPOINT="httpbin.espressif.cn" diff --git a/examples/protocols/esp_local_ctrl/sdkconfig.ci b/examples/protocols/esp_local_ctrl/sdkconfig.ci index 543e69e76e9..0e9f701a68d 100644 --- a/examples/protocols/esp_local_ctrl/sdkconfig.ci +++ b/examples/protocols/esp_local_ctrl/sdkconfig.ci @@ -1 +1,2 @@ CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y +CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/protocols/http_server/file_serving/partitions_example_c5.csv b/examples/protocols/http_server/file_serving/partitions_example_c5.csv new file mode 100644 index 00000000000..c9436240783 --- /dev/null +++ b/examples/protocols/http_server/file_serving/partitions_example_c5.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 0x110000, +storage, data, spiffs, , 0xE0000, diff --git a/examples/protocols/http_server/file_serving/sdkconfig.defaults.esp32c5 b/examples/protocols/http_server/file_serving/sdkconfig.defaults.esp32c5 new file mode 100644 index 00000000000..46b22a2b960 --- /dev/null +++ b/examples/protocols/http_server/file_serving/sdkconfig.defaults.esp32c5 @@ -0,0 +1,5 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example_c5.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_example_c5.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" diff --git a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c index 27109aba6d1..5445559b89a 100644 --- a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c +++ b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c @@ -9,7 +9,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2015-2025 Espressif Systems (Shanghai) CO LTD */ #include #include @@ -27,8 +27,6 @@ #include "mbedtls/net_sockets.h" #include "mbedtls/esp_debug.h" #include "mbedtls/ssl.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #include "mbedtls/error.h" #ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 #include "psa/crypto.h" @@ -54,36 +52,18 @@ static void https_get_task(void *pvParameters) char buf[512]; int ret, flags, len; - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_x509_crt cacert; mbedtls_ssl_config conf; mbedtls_net_context server_fd; -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - psa_status_t status = psa_crypto_init(); - if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Failed to initialize PSA crypto, returned %d", (int) status); - return; - } -#endif - mbedtls_ssl_init(&ssl); mbedtls_x509_crt_init(&cacert); - mbedtls_ctr_drbg_init(&ctr_drbg); + // mbedtls_ctr_drbg_init(&ctr_drbg); ESP_LOGI(TAG, "Seeding the random number generator"); mbedtls_ssl_config_init(&conf); - mbedtls_entropy_init(&entropy); - if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) - { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned %d", ret); - abort(); - } - ESP_LOGI(TAG, "Attaching the certificate bundle..."); ret = esp_crt_bundle_attach(&conf); @@ -116,7 +96,6 @@ static void https_get_task(void *pvParameters) mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED); mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); - mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); #ifdef CONFIG_MBEDTLS_DEBUG mbedtls_esp_enable_debug_log(&conf, CONFIG_MBEDTLS_DEBUG_LEVEL); #endif diff --git a/examples/protocols/https_request/sdkconfig.ci.mbedtls_config b/examples/protocols/https_request/dont_use_with_psa.sdkconfig.ci.mbedtls_config similarity index 100% rename from examples/protocols/https_request/sdkconfig.ci.mbedtls_config rename to examples/protocols/https_request/dont_use_with_psa.sdkconfig.ci.mbedtls_config diff --git a/examples/protocols/https_request/main/https_request_example_main.c b/examples/protocols/https_request/main/https_request_example_main.c index abbb050ac7b..6985f6ea8b9 100644 --- a/examples/protocols/https_request/main/https_request_example_main.c +++ b/examples/protocols/https_request/main/https_request_example_main.c @@ -44,6 +44,7 @@ #include "esp_crt_bundle.h" #endif #include "time_sync.h" +#include "esp_random.h" /* Constants that aren't configurable in menuconfig */ #ifdef CONFIG_EXAMPLE_SSL_PROTO_TLS1_3_CLIENT @@ -95,7 +96,7 @@ extern const uint8_t local_server_cert_pem_end[] asm("_binary_local_server_cer static const int server_supported_ciphersuites[] = {MBEDTLS_TLS1_3_AES_256_GCM_SHA384, MBEDTLS_TLS1_3_AES_128_CCM_SHA256, 0}; static const int server_unsupported_ciphersuites[] = {MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, 0}; #else -static const int server_supported_ciphersuites[] = {MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 0}; +static const int server_supported_ciphersuites[] = {MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, 0}; static const int server_unsupported_ciphersuites[] = {MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, 0}; #endif // CONFIG_EXAMPLE_SSL_PROTO_TLS1_3_CLIENT #endif // CONFIG_EXAMPLE_USING_ESP_TLS_MBEDTLS diff --git a/examples/protocols/https_request/sdkconfig.ci.esp32c2_rom_mbedtls b/examples/protocols/https_request/sdkconfig.ci.esp32c2_rom_mbedtls index 40d3055d5fe..04000befa49 100644 --- a/examples/protocols/https_request/sdkconfig.ci.esp32c2_rom_mbedtls +++ b/examples/protocols/https_request/sdkconfig.ci.esp32c2_rom_mbedtls @@ -2,4 +2,5 @@ CONFIG_IDF_TARGET="esp32c2" CONFIG_XTAL_FREQ_26=y CONFIG_EXAMPLE_CONNECT_WIFI=y CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y -CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=y +# TODO: IDF-15012 +CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=n diff --git a/examples/protocols/https_server/simple/main/main.c b/examples/protocols/https_server/simple/main/main.c index 3d1488af927..eaacb32f998 100644 --- a/examples/protocols/https_server/simple/main/main.c +++ b/examples/protocols/https_server/simple/main/main.c @@ -175,8 +175,8 @@ static httpd_handle_t start_webserver(void) #if CONFIG_EXAMPLE_ENABLE_HTTPS_SERVER_CUSTOM_CIPHERSUITES static const int ciphersuites_to_use[] = { - MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, - MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 0, diff --git a/examples/protocols/https_server/simple/pytest_https_server_simple.py b/examples/protocols/https_server/simple/pytest_https_server_simple.py index 3691ec56af9..4cf68979abd 100644 --- a/examples/protocols/https_server/simple/pytest_https_server_simple.py +++ b/examples/protocols/https_server/simple/pytest_https_server_simple.py @@ -362,7 +362,7 @@ def test_examples_protocol_https_server_tls1_2_only(dut: Dut) -> None: conn.close() # Now try with the matching ciphersuite - ssl_context.set_ciphers('DHE-RSA-AES128-SHA256') + ssl_context.set_ciphers('ECDHE-RSA-AES128-SHA256') conn = http.client.HTTPSConnection(got_ip, got_port, context=ssl_context) logging.info('Performing SSL handshake with the server') diff --git a/examples/protocols/smtp_client/main/smtp_client_example_main.c b/examples/protocols/smtp_client/main/smtp_client_example_main.c index f271c03db02..8f6926e7e06 100644 --- a/examples/protocols/smtp_client/main/smtp_client_example_main.c +++ b/examples/protocols/smtp_client/main/smtp_client_example_main.c @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2015-2025 Espressif Systems (Shanghai) CO LTD */ #include #include @@ -23,8 +23,6 @@ #include "mbedtls/net_sockets.h" #include "mbedtls/esp_debug.h" #include "mbedtls/ssl.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" #include "mbedtls/error.h" #include #include @@ -246,8 +244,6 @@ static void smtp_client_task(void *pvParameters) int ret, len; size_t base64_len; - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_x509_crt cacert; mbedtls_ssl_config conf; @@ -255,18 +251,11 @@ static void smtp_client_task(void *pvParameters) mbedtls_ssl_init(&ssl); mbedtls_x509_crt_init(&cacert); - mbedtls_ctr_drbg_init(&ctr_drbg); + // mbedtls_ctr_drbg_init(&ctr_drbg); ESP_LOGI(TAG, "Seeding the random number generator"); mbedtls_ssl_config_init(&conf); - mbedtls_entropy_init(&entropy); - if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { - ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%x", -ret); - goto exit; - } - ESP_LOGI(TAG, "Loading the CA root certificate..."); ret = mbedtls_x509_crt_parse(&cacert, server_root_cert_pem_start, @@ -297,7 +286,6 @@ static void smtp_client_task(void *pvParameters) mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED); mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); - mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); #ifdef CONFIG_MBEDTLS_DEBUG mbedtls_esp_enable_debug_log(&conf, 4); #endif @@ -476,8 +464,6 @@ exit: mbedtls_x509_crt_free(&cacert); mbedtls_ssl_free(&ssl); mbedtls_ssl_config_free(&conf); - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); if (ret != 0) { mbedtls_strerror(ret, buf, 100); diff --git a/examples/provisioning/wifi_prov_mgr/partitions.csv b/examples/provisioning/wifi_prov_mgr/partitions.csv new file mode 100644 index 00000000000..d91be44e404 --- /dev/null +++ b/examples/provisioning/wifi_prov_mgr/partitions.csv @@ -0,0 +1,5 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, , 0x6000, +phy_init, data, phy, , 0x1000, +factory, app, factory, , 0x170000, diff --git a/examples/security/tee/tee_basic/components/example_secure_service/example_service.c b/examples/security/tee/tee_basic/components/example_secure_service/example_service.c index ba8b738da61..11bc61b2a77 100644 --- a/examples/security/tee/tee_basic/components/example_secure_service/example_service.c +++ b/examples/security/tee/tee_basic/components/example_secure_service/example_service.c @@ -8,7 +8,11 @@ #include "esp_err.h" #include "esp_log.h" +#if CONFIG_MBEDTLS_VER_4_X_SUPPORT +#include "psa/crypto.h" +#else #include "mbedtls/gcm.h" +#endif #include "esp_tee.h" #include "secure_service_num.h" @@ -45,11 +49,73 @@ static esp_err_t aes_gcm_crypt_common(example_aes_gcm_ctx_t *ctx, uint8_t *tag, ESP_LOGI(TAG, "Secure service call: PROTECTED M-mode"); ESP_LOGI(TAG, "AES-256-GCM %s", is_encrypt ? "encryption" : "decryption"); + esp_err_t err = ESP_FAIL; +#if CONFIG_MBEDTLS_VER_4_X_SUPPORT + psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; + psa_status_t status; + psa_key_id_t key_id; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_algorithm_t alg = PSA_ALG_GCM; + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&key_attributes, alg); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, AES256_KEY_BITS); + status = psa_import_key(&key_attributes, key, sizeof(key), &key_id); + psa_reset_key_attributes(&key_attributes); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in importing key: %d", status); + return ESP_ERR_INVALID_STATE; + } + if (is_encrypt) { + status = psa_aead_encrypt_setup(&operation, key_id, alg); + } else { + status = psa_aead_decrypt_setup(&operation, key_id, alg); + } + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in AEAD setup: %d", status); + goto cleanup; + } + status = psa_aead_set_lengths(&operation, ctx->aad_len, ctx->input_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in setting lengths: %d", status); + goto cleanup; + } + psa_aead_set_nonce(&operation, nonce, AES256_NONCE_LEN); + if (ctx->aad_len > 0) { + status = psa_aead_update_ad(&operation, ctx->aad, ctx->aad_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in updating AAD: %d", status); + goto cleanup; + } + } + + size_t output_len = 0; + status = psa_aead_update(&operation, ctx->input, ctx->input_len, output, ctx->input_len, &output_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in updating aead: %d", status); + goto cleanup; + } + + if (is_encrypt) { + size_t output_tag_len = 0; + status = psa_aead_finish(&operation, output + output_len, ctx->input_len + tag_len - output_len, &output_len, tag, tag_len, &output_tag_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in finishing encryption: %d", status); + goto cleanup; + } + } else { + size_t plaintext_len = 0; + status = psa_aead_verify(&operation, output, ctx->input_len, &plaintext_len, tag, tag_len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Error in verifying decryption: %d", status); + goto cleanup; + } + } + err = ESP_OK; +#else mbedtls_gcm_context gcm; mbedtls_gcm_init(&gcm); - esp_err_t err = ESP_FAIL; - int ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, AES256_KEY_BITS); if (ret != 0) { ESP_LOGE(TAG, "Error in setting key: %d", ret); @@ -78,9 +144,15 @@ static esp_err_t aes_gcm_crypt_common(example_aes_gcm_ctx_t *ctx, uint8_t *tag, } } err = ESP_OK; +#endif cleanup: +#if CONFIG_MBEDTLS_VER_4_X_SUPPORT + psa_aead_abort(&operation); + psa_destroy_key(key_id); +#else mbedtls_gcm_free(&gcm); +#endif return err; } diff --git a/examples/security/tee/tee_basic/main/tee_main.c b/examples/security/tee/tee_basic/main/tee_main.c index e050320b9e4..22f58a1923d 100644 --- a/examples/security/tee/tee_basic/main/tee_main.c +++ b/examples/security/tee/tee_basic/main/tee_main.c @@ -17,7 +17,7 @@ #include "example_service.h" #define EXAMPLE_BUF_SZ (32) -#define AES256_GCM_TAG_LEN (12) +#define AES256_GCM_TAG_LEN (16) #define AES256_GCM_AAD_LEN (16) static const char *TAG = "example_tee_basic"; diff --git a/examples/security/tee/tee_basic/sdkconfig.defaults b/examples/security/tee/tee_basic/sdkconfig.defaults index 214076f76ef..f34703bed79 100644 --- a/examples/security/tee/tee_basic/sdkconfig.defaults +++ b/examples/security/tee/tee_basic/sdkconfig.defaults @@ -4,3 +4,4 @@ CONFIG_SECURE_TEE_LOG_LEVEL_INFO=y CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y CONFIG_SECURE_TEE_ATTESTATION=n CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n +CONFIG_SECURE_TEE_IRAM_SIZE=0xC000 diff --git a/examples/security/tee/tee_secure_storage/README.md b/examples/security/tee/tee_secure_storage/README.md index f44ed6dd82b..579d93d69af 100644 --- a/examples/security/tee/tee_secure_storage/README.md +++ b/examples/security/tee/tee_secure_storage/README.md @@ -29,7 +29,9 @@ Before the project configuration and build, be sure to set the correct chip targ Open the project configuration menu (`idf.py menuconfig`). -- Configure the secure storage example key ID at `Example Configuration → TEE: Secure Storage Key ID`. +- Configure unique secure storage key IDs for each workflow: + - `Example Configuration → TEE: Secure Storage Key ID for signing` + - `Example Configuration → TEE: Secure Storage Key ID for encryption` TEE Secure Storage follows the NVS partition format and uses an XTS-AES encryption scheme derived via the HMAC peripheral or software-based HMAC implementation. It supports two key derivation modes, configurable via `CONFIG_SECURE_TEE_SEC_STG_MODE`: diff --git a/examples/security/tee/tee_secure_storage/main/Kconfig.projbuild b/examples/security/tee/tee_secure_storage/main/Kconfig.projbuild index 0246a1e9352..8f5b66130e9 100644 --- a/examples/security/tee/tee_secure_storage/main/Kconfig.projbuild +++ b/examples/security/tee/tee_secure_storage/main/Kconfig.projbuild @@ -1,11 +1,17 @@ menu "Example Configuration" - config EXAMPLE_TEE_SEC_STG_KEY_STR_ID - string "TEE: Secure Storage Key ID" - default "key_id_0" + config EXAMPLE_TEE_SEC_STG_SIGN_KEY_STR_ID + string "TEE: Secure Storage Key ID for signing" + default "sign_key_id_0" help - This configuration sets the key string identifier from the TEE secure storage - storing the ECDSA keypair for executing sign/verify operations - from the TEE side + Identifier for the ECDSA keypair stored in secure storage and used for + sign/verify operations in this example. + + config EXAMPLE_TEE_SEC_STG_ENC_KEY_STR_ID + string "TEE: Secure Storage Key ID for encryption" + default "aes_key_id_0" + help + Identifier for the AES-256 key stored in secure storage and used for + the AEAD encryption/decryption part of this example. endmenu diff --git a/examples/security/tee/tee_secure_storage/main/tee_main.c b/examples/security/tee/tee_secure_storage/main/tee_main.c index 767a9fbd7d7..c1211de891f 100644 --- a/examples/security/tee/tee_secure_storage/main/tee_main.c +++ b/examples/security/tee/tee_secure_storage/main/tee_main.c @@ -15,9 +15,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "mbedtls/ecp.h" -#include "mbedtls/ecdsa.h" -#include "mbedtls/sha256.h" +#include "psa/crypto.h" #include "esp_tee_sec_storage.h" #include "secure_service_num.h" @@ -28,7 +26,8 @@ #define AES256_GCM_TAG_LEN (16) #define AES256_GCM_AAD_LEN (16) -#define KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_KEY_STR_ID) +#define SIGN_KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_SIGN_KEY_STR_ID) +#define ENC_KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_ENC_KEY_STR_ID) #define MAX_AES_PLAINTEXT_LEN (128) static const char *message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; @@ -47,56 +46,33 @@ static esp_err_t verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, esp_err_t err = ESP_FAIL; - mbedtls_mpi r, s; - mbedtls_mpi_init(&r); - mbedtls_mpi_init(&s); + psa_key_id_t key_id = 0; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); - mbedtls_ecdsa_context ecdsa_context; - mbedtls_ecdsa_init(&ecdsa_context); + uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN + 1]; + pub_key[0] = 0x04; + memcpy(pub_key + 1, pubkey->pub_x, ECDSA_SECP256R1_KEY_LEN); + memcpy(pub_key + 1 + ECDSA_SECP256R1_KEY_LEN, pubkey->pub_y, ECDSA_SECP256R1_KEY_LEN); - int ret = mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); - if (ret != 0) { + psa_status_t status = psa_import_key(&key_attributes, pub_key, sizeof(pub_key), &key_id); + if (status != PSA_SUCCESS) { goto exit; } - size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P); - - ret = mbedtls_mpi_read_binary(&r, sign->sign_r, plen); - if (ret != 0) { + status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, sizeof(sign->signature)); + if (status != PSA_SUCCESS) { goto exit; } - ret = mbedtls_mpi_read_binary(&s, sign->sign_s, plen); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1); - if (ret != 0) { - goto exit; - } - - ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s); - if (ret != 0) { - goto exit; - } + psa_destroy_key(key_id); + psa_reset_key_attributes(&key_attributes); err = ESP_OK; exit: - mbedtls_mpi_free(&r); - mbedtls_mpi_free(&s); - mbedtls_ecdsa_free(&ecdsa_context); return err; } @@ -107,14 +83,15 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter) ESP_LOGI(TAG, "Message-to-be-signed: %s", msg); uint8_t msg_digest[SHA256_DIGEST_SZ]; - int ret = mbedtls_sha256((const unsigned char *)msg, strlen(msg), msg_digest, false); - if (ret != 0) { + size_t msg_digest_len = 0; + psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t *)msg, strlen(msg), msg_digest, sizeof(msg_digest), &msg_digest_len); + if (status != PSA_SUCCESS) { ESP_LOGE(TAG, "Failed to calculate message hash!"); goto exit; } esp_tee_sec_storage_key_cfg_t cfg = { - .id = (const char *)(KEY_STR_ID), + .id = (const char *)(SIGN_KEY_STR_ID), .type = ESP_SEC_STG_KEY_ECDSA_SECP256R1 }; @@ -131,7 +108,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter) } esp_tee_sec_storage_ecdsa_sign_t sign = {}; - err = esp_tee_sec_storage_ecdsa_sign(&cfg, msg_digest, sizeof(msg_digest), &sign); + err = esp_tee_sec_storage_ecdsa_sign(&cfg, msg_digest, msg_digest_len, &sign); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to generate signature!"); goto exit; @@ -146,7 +123,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter) goto exit; } - err = verify_ecdsa_secp256r1_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign); + err = verify_ecdsa_secp256r1_sign(msg_digest, msg_digest_len, &pubkey, &sign); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to verify signature!"); goto exit; @@ -182,7 +159,7 @@ static void example_tee_sec_stg_encrypt_decrypt(void *pvParameter) } esp_tee_sec_storage_key_cfg_t cfg = { - .id = (const char *)(KEY_STR_ID), + .id = (const char *)(ENC_KEY_STR_ID), .type = ESP_SEC_STG_KEY_AES256 }; diff --git a/examples/storage/nvs/.build-test-rules.yml b/examples/storage/nvs/.build-test-rules.yml index d28db77c11a..29c5a8ab1e2 100644 --- a/examples/storage/nvs/.build-test-rules.yml +++ b/examples/storage/nvs/.build-test-rules.yml @@ -8,6 +8,9 @@ examples/storage/nvs/nvs_bootloader: - if: CONFIG_NAME == "nvs_enc_flash_enc" and (SOC_AES_SUPPORTED != 1 and ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB != 1) - if: CONFIG_NAME == "nvs_enc_hmac" and (SOC_HMAC_SUPPORTED != 1 or (SOC_HMAC_SUPPORTED == 1 and (SOC_AES_SUPPORTED != 1 and ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB != 1))) reason: As of now in such cases, we do not have any way to perform AES operations in the bootloader build + # TODO: IDF-15012 + - if: IDF_TARGET in ["esp32c2"] + reason: PSA is not yet available for ESP32-C2 examples/storage/nvs/nvs_console: depends_components: diff --git a/examples/storage/nvs/nvs_bootloader/README.md b/examples/storage/nvs/nvs_bootloader/README.md index 8d1f7dda6b1..50d209cd546 100644 --- a/examples/storage/nvs/nvs_bootloader/README.md +++ b/examples/storage/nvs/nvs_bootloader/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | # NVS Bootloader diff --git a/examples/storage/spiffsgen/main/spiffsgen_example_main.c b/examples/storage/spiffsgen/main/spiffsgen_example_main.c index c5efb039b62..cdcbdde9f8b 100644 --- a/examples/storage/spiffsgen/main/spiffsgen_example_main.c +++ b/examples/storage/spiffsgen/main/spiffsgen_example_main.c @@ -1,6 +1,6 @@ /* SPIFFS Image Generation on Build Example * - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense or CC0-1.0 */ @@ -11,7 +11,7 @@ #include "esp_err.h" #include "esp_log.h" #include "esp_spiffs.h" -#include "mbedtls/md5.h" +#include "psa/crypto.h" static const char *TAG = "example"; @@ -50,20 +50,36 @@ static void compute_alice_txt_md5(void) #define MD5_MAX_LEN 16 char buf[64]; - mbedtls_md5_context ctx; - unsigned char digest[MD5_MAX_LEN]; + psa_status_t status; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + psa_algorithm_t alg = PSA_ALG_MD5; + status = psa_hash_setup(&operation, alg); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to setup hash operation"); + return; + } - mbedtls_md5_init(&ctx); - mbedtls_md5_starts(&ctx); + size_t md5_len = PSA_HASH_LENGTH(alg); + + unsigned char digest[md5_len]; size_t read; do { read = fread((void*) buf, 1, sizeof(buf), f); - mbedtls_md5_update(&ctx, (unsigned const char*) buf, read); + status = psa_hash_update(&operation, (unsigned const char*) buf, read); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to update hash operation"); + return; + } } while(read == sizeof(buf)); - mbedtls_md5_finish(&ctx, digest); + size_t md5len = 0; + status = psa_hash_finish(&operation, digest, md5_len, &md5len); + if (status != PSA_SUCCESS) { + ESP_LOGE(TAG, "Failed to finish hash operation"); + return; + } // Create a string of the digest char digest_str[MD5_MAX_LEN * 2]; diff --git a/examples/storage/spiffsgen/sdkconfig.defaults b/examples/storage/spiffsgen/sdkconfig.defaults index b9bb0c0a5dc..bd38dbbf59a 100644 --- a/examples/storage/spiffsgen/sdkconfig.defaults +++ b/examples/storage/spiffsgen/sdkconfig.defaults @@ -1,3 +1,6 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv" +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv" diff --git a/examples/system/console/advanced/partitions_example.csv b/examples/system/console/advanced/partitions_example.csv index 1c79321a107..27472b2454b 100644 --- a/examples/system/console/advanced/partitions_example.csv +++ b/examples/system/console/advanced/partitions_example.csv @@ -2,5 +2,5 @@ # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, -factory, app, factory, 0x10000, 1M, +factory, app, factory, 0x10000, 0x110000, storage, data, fat, , 1M, diff --git a/examples/system/console/basic/partitions_example.csv b/examples/system/console/basic/partitions_example.csv index 1c79321a107..27472b2454b 100644 --- a/examples/system/console/basic/partitions_example.csv +++ b/examples/system/console/basic/partitions_example.csv @@ -2,5 +2,5 @@ # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, -factory, app, factory, 0x10000, 1M, +factory, app, factory, 0x10000, 0x110000, storage, data, fat, , 1M, diff --git a/examples/system/ota/advanced_https_ota/partitions_example_with_ble.csv b/examples/system/ota/advanced_https_ota/partitions_example_with_ble.csv index dd7501cb4ff..e629d8da8b9 100644 --- a/examples/system/ota/advanced_https_ota/partitions_example_with_ble.csv +++ b/examples/system/ota/advanced_https_ota/partitions_example_with_ble.csv @@ -4,5 +4,5 @@ nvs, data, nvs, , 0x4000, otadata, data, ota, , 0x2000, phy_init, data, phy, , 0x1000, -ota_0, app, ota_0, , 1500K, -ota_1, app, ota_1, , 1500K, +ota_0, app, ota_0, , 1600K, +ota_1, app, ota_1, , 1600K, diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index c9108712185..b532452594a 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -468,7 +468,6 @@ components/mbedtls/port/aes/esp_aes_xts.c components/mbedtls/port/include/aes/esp_aes.h components/mbedtls/port/include/aes_alt.h components/mbedtls/port/include/bignum_impl.h -components/mbedtls/port/include/mbedtls/esp_debug.h components/mbedtls/port/include/sha1_alt.h components/mbedtls/port/include/sha256_alt.h components/mbedtls/port/include/sha512_alt.h diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index 4600b54cf00..01b0cf29995 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -777,7 +777,7 @@ def test_dcache_read_violation(dut: PanicTestDut, test_func_name: str) -> None: # TODO: IDF-6820: ESP32-S2 -> Fix multiple panic reasons in different runs @pytest.mark.generic -@pytest.mark.xfail('config.getvalue("target") == "esp32s2"', reason='Incorrect panic reason may be observed', run=False) +@pytest.mark.xfail(targets=['esp32s2'], reason='Incorrect panic reason may be observed', run=False) @idf_parametrize('config, target', CONFIGS_MEMPROT_DCACHE, indirect=['config', 'target']) def test_dcache_write_violation(dut: PanicTestDut, test_func_name: str) -> None: dut.run_test_func(test_func_name) @@ -919,7 +919,7 @@ def iram_reg4_write_violation(dut: PanicTestDut, test_func_name: str) -> None: # TODO: IDF-6820: ESP32-S2 -> Fix incorrect panic reason: Unhandled debug exception @pytest.mark.generic -@pytest.mark.xfail('config.getvalue("target") == "esp32s2"', reason='Incorrect panic reason may be observed', run=False) +@pytest.mark.xfail(targets=['esp32s2'], reason='Incorrect panic reason may be observed', run=False) @pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners') @idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target']) def test_iram_reg4_write_violation(dut: PanicTestDut, test_func_name: str) -> None: @@ -951,9 +951,7 @@ def dram_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) -> None: # TODO: IDF-6820: ESP32-S2 -> Fix multiple panic reasons in different runs @pytest.mark.generic -@pytest.mark.xfail( - 'config.getvalue("target") == "esp32s2"', reason='Multiple panic reasons for the same test may surface', run=False -) +@pytest.mark.xfail(targets=['esp32s2'], reason='Multiple panic reasons for the same test may surface', run=False) @pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners') @idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target']) def test_dram_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) -> None: @@ -984,9 +982,7 @@ def dram_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) -> None: # TODO: IDF-6820: ESP32-S2 -> Fix multiple panic reasons in different runs @pytest.mark.generic -@pytest.mark.xfail( - 'config.getvalue("target") == "esp32s2"', reason='Multiple panic reasons for the same test may surface', run=False -) +@pytest.mark.xfail(targets=['esp32s2'], reason='Multiple panic reasons for the same test may surface', run=False) @pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners') @idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target']) def test_dram_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) -> None: @@ -1035,9 +1031,7 @@ def test_rtc_fast_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) # TODO: IDF-6820: ESP32-S2 -> Fix multiple panic reasons in different runs @pytest.mark.generic -@pytest.mark.xfail( - 'config.getvalue("target") == "esp32s2"', reason='Multiple panic reasons for the same test may surface', run=False -) +@pytest.mark.xfail(targets=['esp32s2'], reason='Multiple panic reasons for the same test may surface', run=False) @pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners') @idf_parametrize('config, target', CONFIGS_MEMPROT_RTC_FAST_MEM, indirect=['config', 'target']) def test_rtc_fast_reg3_execute_violation(dut: PanicTestDut, test_func_name: str) -> None: diff --git a/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_bin_crc b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_bin_crc new file mode 100644 index 00000000000..96f77e18aaa --- /dev/null +++ b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_bin_crc @@ -0,0 +1,5 @@ +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +CONFIG_LOG_DEFAULT_LEVEL_INFO=y + +# static D/IRAM usage 97%, add this to reduce +CONFIG_HAL_ASSERTION_DISABLE=y