diff --git a/components/esp_tee/scripts/esp32c5/sec_srv_tbl_default.yml b/components/esp_tee/scripts/esp32c5/sec_srv_tbl_default.yml index 473b16e2c2..4ff99e0e2a 100644 --- a/components/esp_tee/scripts/esp32c5/sec_srv_tbl_default.yml +++ b/components/esp_tee/scripts/esp32c5/sec_srv_tbl_default.yml @@ -334,11 +334,11 @@ secure_services: - id: 179 type: custom function: esp_tee_sec_storage_aead_encrypt - args: 4 + args: 6 - id: 180 type: custom function: esp_tee_sec_storage_aead_decrypt - args: 4 + args: 6 - id: 181 type: custom function: esp_tee_sec_storage_ecdsa_sign_pbkdf2 diff --git a/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml b/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml index 4890d1e5e8..16fa321453 100644 --- a/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml +++ b/components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml @@ -274,11 +274,11 @@ secure_services: - id: 179 type: custom function: esp_tee_sec_storage_aead_encrypt - args: 4 + args: 6 - id: 180 type: custom function: esp_tee_sec_storage_aead_decrypt - args: 4 + args: 6 - id: 181 type: custom function: esp_tee_sec_storage_ecdsa_sign_pbkdf2 diff --git a/components/esp_tee/scripts/esp32c61/sec_srv_tbl_default.yml b/components/esp_tee/scripts/esp32c61/sec_srv_tbl_default.yml index f334bb360d..2f07a5812d 100644 --- a/components/esp_tee/scripts/esp32c61/sec_srv_tbl_default.yml +++ b/components/esp_tee/scripts/esp32c61/sec_srv_tbl_default.yml @@ -239,11 +239,11 @@ secure_services: - id: 179 type: custom function: esp_tee_sec_storage_aead_encrypt - args: 4 + args: 6 - id: 180 type: custom function: esp_tee_sec_storage_aead_decrypt - args: 4 + args: 6 # ID: 195-199 (5) - OTA - family: ota entries: diff --git a/components/esp_tee/scripts/esp32h2/sec_srv_tbl_default.yml b/components/esp_tee/scripts/esp32h2/sec_srv_tbl_default.yml index b6a775b878..0a5321f6e2 100644 --- a/components/esp_tee/scripts/esp32h2/sec_srv_tbl_default.yml +++ b/components/esp_tee/scripts/esp32h2/sec_srv_tbl_default.yml @@ -278,11 +278,11 @@ secure_services: - id: 179 type: custom function: esp_tee_sec_storage_aead_encrypt - args: 4 + args: 6 - id: 180 type: custom function: esp_tee_sec_storage_aead_decrypt - args: 4 + args: 6 - id: 181 type: custom function: esp_tee_sec_storage_ecdsa_sign_pbkdf2 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 8889f93571..8d863f459b 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -144,25 +144,29 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg * @brief Perform encryption using AES256-GCM with the key from secure storage * * @param[in] ctx Pointer to the AEAD operation context + * @param[out] iv Pointer to the output buffer for the generated initialization vector + * @param[in] iv_len Length of the initialization vector buffer * @param[out] tag Pointer to the authentication tag buffer * @param[in] tag_len Length of the authentication tag * @param[out] output Pointer to the output data buffer * * @return esp_err_t ESP_OK on success, appropriate error code otherwise. */ -esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output); +esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *iv, size_t iv_len, uint8_t *tag, size_t tag_len, uint8_t *output); /** * @brief Perform decryption using AES256-GCM with the key from secure storage * * @param[in] ctx Pointer to the AEAD operation context + * @param[in] iv Pointer to the initialization vector used during encryption + * @param[in] iv_len Length of the initialization vector * @param[in] tag Pointer to the authentication tag buffer * @param[in] tag_len Length of the authentication tag * @param[out] output Pointer to the output data buffer * * @return esp_err_t ESP_OK on success, appropriate error code otherwise. */ -esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output); +esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *iv, size_t iv_len, const uint8_t *tag, size_t tag_len, uint8_t *output); /** * @brief Generate and return the signature for the specified message digest using 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 e34a17307a..48d960bacc 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 @@ -388,7 +388,6 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t size_t pub_key_buf_size = 0; esp_err_t err = get_ecdsa_curve_info(key_type, keyctx, &priv_key_buf, &priv_key_buf_size, &pub_key_buf, &pub_key_buf_size); if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to get ECDSA curve info: %d", err); return -1; } psa_set_key_bits(&key_attributes, priv_key_buf_size * 8); @@ -398,7 +397,6 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t 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; } @@ -407,7 +405,6 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t 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; } @@ -421,7 +418,6 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t 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; } @@ -431,7 +427,7 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t 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"); + ESP_LOGD(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; @@ -560,7 +556,6 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf psa_status_t status = psa_import_key(&key_attributes, priv_key, priv_key_len, &key_id); if (status != PSA_SUCCESS) { err = ESP_ERR_INVALID_ARG; - ESP_LOGE(TAG, "Failed to import ECDSA private key: %ld", status); goto exit; } @@ -636,16 +631,16 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg } static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t *input, size_t len, const uint8_t *aad, - size_t aad_len, uint8_t *tag, size_t tag_len, uint8_t *output, - bool is_encrypt) + size_t aad_len, uint8_t *iv, size_t iv_len, uint8_t *tag, size_t tag_len, + uint8_t *output, bool is_encrypt) { - if (key_id == NULL || input == NULL || output == NULL || tag == NULL) { + if (key_id == NULL || input == NULL || output == NULL || tag == NULL || iv == NULL) { ESP_LOGE(TAG, "Invalid arguments"); return ESP_ERR_INVALID_ARG; } - if (len == 0 || tag_len == 0) { - ESP_LOGE(TAG, "Invalid input/tag length"); + if (len == 0 || tag_len == 0 || iv_len == 0) { + ESP_LOGE(TAG, "Invalid input/tag/iv length"); return ESP_ERR_INVALID_SIZE; } @@ -682,7 +677,6 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t psa_reset_key_attributes(&attributes); if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Failed to import AES key: %d", status); return ESP_FAIL; } @@ -690,16 +684,15 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t // PSA AEAD encrypt outputs ciphertext+tag concatenated uint8_t *output_with_tag = malloc(len + tag_len); if (!output_with_tag) { - ESP_LOGE(TAG, "Failed to allocate memory"); psa_destroy_key(key_id_psa); return ESP_ERR_NO_MEM; } + esp_fill_random(iv, iv_len); + size_t output_length = 0; status = psa_aead_encrypt(key_id_psa, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len), - keyctx.aes256.iv, AES256_GCM_IV_LEN, - aad, aad_len, - input, len, + iv, iv_len, aad, aad_len, input, len, output_with_tag, len + tag_len, &output_length); if (status != PSA_SUCCESS) { ESP_LOGE(TAG, "Error in encrypting data: %d", status); @@ -719,7 +712,6 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t // For decryption, PSA expects ciphertext + tag concatenated uint8_t *input_with_tag = malloc(len + tag_len); if (!input_with_tag) { - ESP_LOGE(TAG, "Failed to allocate memory"); psa_destroy_key(key_id_psa); return ESP_ERR_NO_MEM; } @@ -729,9 +721,7 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t size_t output_length = 0; status = psa_aead_decrypt(key_id_psa, PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, tag_len), - keyctx.aes256.iv, AES256_GCM_IV_LEN, - aad, aad_len, - input_with_tag, len + tag_len, + iv, iv_len, aad, aad_len, input_with_tag, len + tag_len, output, len, &output_length); memset(input_with_tag, 0x00, len + tag_len); @@ -748,14 +738,14 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t return ESP_OK; } -esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output) +esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *iv, size_t iv_len, uint8_t *tag, size_t tag_len, uint8_t *output) { - return tee_sec_storage_crypt_common(ctx->key_id, ctx->input, ctx->input_len, ctx->aad, ctx->aad_len, tag, tag_len, output, true); + return tee_sec_storage_crypt_common(ctx->key_id, ctx->input, ctx->input_len, ctx->aad, ctx->aad_len, iv, iv_len, tag, tag_len, output, true); } -esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output) +esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *iv, size_t iv_len, const uint8_t *tag, size_t tag_len, uint8_t *output) { - return tee_sec_storage_crypt_common(ctx->key_id, ctx->input, ctx->input_len, ctx->aad, ctx->aad_len, (uint8_t *)tag, tag_len, output, false); + return tee_sec_storage_crypt_common(ctx->key_id, ctx->input, ctx->input_len, ctx->aad, ctx->aad_len, (uint8_t *)iv, iv_len, (uint8_t *)tag, tag_len, output, false); } #if SOC_HMAC_SUPPORTED @@ -826,7 +816,6 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2 psa_reset_key_attributes(&attributes); if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Failed to import ECC private key: %d", status); err = ESP_FAIL; goto exit; } @@ -838,7 +827,6 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2 hash, hlen, out_sign->signature, sizeof(out_sign->signature), &signature_length); if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Failed to sign hash: %d", status); memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t)); err = ESP_FAIL; goto exit; @@ -850,7 +838,6 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2 size_t public_key_length = 0; status = psa_export_public_key(psa_key_id, public_key, sizeof(public_key), &public_key_length); if (status != PSA_SUCCESS) { - ESP_LOGE(TAG, "Failed to export public key: %d", status); memset(out_pubkey, 0x00, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t)); err = ESP_FAIL; goto exit; @@ -859,7 +846,6 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2 // PSA exports public key in uncompressed format: 0x04 || X || Y // Skip the first byte (0x04) and copy X and Y coordinates if (public_key_length != (1 + 2 * key_len) || public_key[0] != 0x04) { - ESP_LOGE(TAG, "Unexpected public key format"); memset(out_pubkey, 0x00, sizeof(esp_tee_sec_storage_ecdsa_pubkey_t)); err = ESP_FAIL; goto exit; diff --git a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c index ae1fa9564c..e4b82db00a 100644 --- a/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c +++ b/components/esp_tee/subproject/components/tee_sec_storage/tee_sec_storage_wrapper.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,14 +31,14 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg return esp_tee_service_call_with_noniram_intr_disabled(3, SS_ESP_TEE_SEC_STORAGE_ECDSA_GET_PUBKEY, cfg, out_pubkey); } -esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output) +esp_err_t esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *iv, size_t iv_len, uint8_t *tag, size_t tag_len, uint8_t *output) { - return esp_tee_service_call_with_noniram_intr_disabled(5, SS_ESP_TEE_SEC_STORAGE_AEAD_ENCRYPT, ctx, tag, tag_len, output); + return esp_tee_service_call_with_noniram_intr_disabled(7, SS_ESP_TEE_SEC_STORAGE_AEAD_ENCRYPT, ctx, iv, iv_len, tag, tag_len, output); } -esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output) +esp_err_t esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *iv, size_t iv_len, const uint8_t *tag, size_t tag_len, uint8_t *output) { - return esp_tee_service_call_with_noniram_intr_disabled(5, SS_ESP_TEE_SEC_STORAGE_AEAD_DECRYPT, ctx, tag, tag_len, output); + return esp_tee_service_call_with_noniram_intr_disabled(7, SS_ESP_TEE_SEC_STORAGE_AEAD_DECRYPT, ctx, iv, iv_len, tag, tag_len, output); } #if SOC_HMAC_SUPPORTED diff --git a/components/esp_tee/subproject/main/core/esp_secure_services_iram.c b/components/esp_tee/subproject/main/core/esp_secure_services_iram.c index dc3437acac..866d40217e 100644 --- a/components/esp_tee/subproject/main/core/esp_secure_services_iram.c +++ b/components/esp_tee/subproject/main/core/esp_secure_services_iram.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -151,13 +151,15 @@ esp_err_t _ss_esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key return esp_tee_sec_storage_ecdsa_get_pubkey(cfg, out_pubkey); } -esp_err_t _ss_esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output) +esp_err_t _ss_esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *iv, size_t iv_len, uint8_t *tag, size_t tag_len, uint8_t *output) { bool valid_addr = (esp_tee_ptr_in_ree((void *)ctx->input) && + esp_tee_ptr_in_ree((void *)iv) && esp_tee_ptr_in_ree((void *)tag) && esp_tee_ptr_in_ree((void *)output)); valid_addr &= (esp_tee_ptr_in_ree((void *)(ctx->input + ctx->input_len)) && + esp_tee_ptr_in_ree((void *)(iv + iv_len)) && esp_tee_ptr_in_ree((void *)(tag + tag_len)) && esp_tee_ptr_in_ree((void *)(output + ctx->input_len))); @@ -170,16 +172,18 @@ esp_err_t _ss_esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ct } ESP_FAULT_ASSERT(valid_addr); - return esp_tee_sec_storage_aead_encrypt(ctx, tag, tag_len, output); + return esp_tee_sec_storage_aead_encrypt(ctx, iv, iv_len, tag, tag_len, output); } -esp_err_t _ss_esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *tag, size_t tag_len, uint8_t *output) +esp_err_t _ss_esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ctx_t *ctx, const uint8_t *iv, size_t iv_len, const uint8_t *tag, size_t tag_len, uint8_t *output) { bool valid_addr = (esp_tee_ptr_in_ree((void *)ctx->input) && + esp_tee_ptr_in_ree((void *)iv) && esp_tee_ptr_in_ree((void *)tag) && esp_tee_ptr_in_ree((void *)output)); valid_addr &= (esp_tee_ptr_in_ree((void *)(ctx->input + ctx->input_len)) && + esp_tee_ptr_in_ree((void *)(iv + iv_len)) && esp_tee_ptr_in_ree((void *)(tag + tag_len)) && esp_tee_ptr_in_ree((void *)(output + ctx->input_len))); @@ -192,7 +196,7 @@ esp_err_t _ss_esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ct } ESP_FAULT_ASSERT(valid_addr); - return esp_tee_sec_storage_aead_decrypt(ctx, tag, tag_len, output); + return esp_tee_sec_storage_aead_decrypt(ctx, iv, iv_len, tag, tag_len, output); } esp_err_t _ss_esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2_ctx_t *ctx, const uint8_t *hash, size_t hlen, esp_tee_sec_storage_ecdsa_sign_t *out_sign, esp_tee_sec_storage_ecdsa_pubkey_t *out_pubkey) diff --git a/components/esp_tee/test_apps/tee_cli_app/README.md b/components/esp_tee/test_apps/tee_cli_app/README.md index 6cd01e7076..a723ec413a 100644 --- a/components/esp_tee/test_apps/tee_cli_app/README.md +++ b/components/esp_tee/test_apps/tee_cli_app/README.md @@ -112,10 +112,11 @@ tee_sec_stg_encrypt <key_id> TEE Secure storage key ID <plaintext> Plaintext to be encrypted -tee_sec_stg_decrypt <key_id> <ciphertext> <tag> +tee_sec_stg_decrypt <key_id> <ciphertext> <iv> <tag> Decrypt data using AES-GCM key with the given ID from secure storage <key_id> TEE Secure storage key ID <ciphertext> Ciphertext to be decrypted + <iv> AES-GCM initialization vector <tag> AES-GCM authentication tag help [<string>] [-v <0|1>] @@ -180,10 +181,12 @@ esp32c6> tee_sec_stg_gen_key aes256_k0 0 I (2784) tee_sec_stg: Generated AES256 key with ID key0 esp32c6> tee_sec_stg_encrypt aes256_k0 b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 I (3084) tee_sec_stg: Ciphertext - -58054310a96d48c2dccdf2e34005aa63b40817723d3ec3d597ab362efea084c1 +f72e44dda3b2d0a44ffc8cafd2f28b7933776dce78684c5514f9398daf3dc344 +I (3294) tee_sec_stg: IV - +ef5c08c05828cf933440f121 I (3594) tee_sec_stg: Tag - -caeedb43e08dc3b4e35a58b2412908cc -esp32c6> tee_sec_stg_decrypt aes256_k0 58054310a96d48c2dccdf2e34005aa63b40817723d3ec3d597ab362efea084c1 caeedb43e08dc3b4e35a58b2412908cc +826a2e65f0e1d8aede1fb12e78957f0d +esp32c6> tee_sec_stg_decrypt aes256_k0 f72e44dda3b2d0a44ffc8cafd2f28b7933776dce78684c5514f9398daf3dc344 ef5c08c05828cf933440f121 826a2e65f0e1d8aede1fb12e78957f0d I (4314) tee_sec_stg: Decrypted plaintext - b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 ``` diff --git a/components/esp_tee/test_apps/tee_cli_app/main/app_main.c b/components/esp_tee/test_apps/tee_cli_app/main/app_main.c index 596d04f02b..256b0cda33 100644 --- a/components/esp_tee/test_apps/tee_cli_app/main/app_main.c +++ b/components/esp_tee/test_apps/tee_cli_app/main/app_main.c @@ -33,7 +33,7 @@ static void setup_console(void) * This can be customized, made dynamic, etc. */ repl_config.prompt = PROMPT_STR ">"; - repl_config.max_cmdline_length = 128; + repl_config.max_cmdline_length = 256; /* Register help command */ ESP_ERROR_CHECK(esp_console_register_help_command()); 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 c1832aafec..7aaa2edeb1 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +28,7 @@ #endif /* CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN */ #define AES256_GCM_TAG_LEN (16) +#define AES256_GCM_IV_LEN (12) #define MAX_AES_PLAINTEXT_LEN (256) #define ECDSA_SECP256R1_KEY_LEN (32) @@ -348,6 +349,7 @@ static int tee_sec_stg_encrypt(int argc, char **argv) esp_err_t err = ESP_FAIL; uint8_t tag[AES256_GCM_TAG_LEN]; + uint8_t iv[AES256_GCM_IV_LEN]; const char *key_id = (const char *)tee_sec_stg_encrypt_args.key_str_id->sval[0]; const char *plaintext = tee_sec_stg_encrypt_args.plaintext->sval[0]; @@ -384,7 +386,7 @@ static int tee_sec_stg_encrypt(int argc, char **argv) .input_len = plaintext_buf_len }; - err = esp_tee_sec_storage_aead_encrypt(&ctx, tag, sizeof(tag), ciphertext_buf); + err = esp_tee_sec_storage_aead_encrypt(&ctx, iv, sizeof(iv), tag, sizeof(tag), ciphertext_buf); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to encrypt data: %s", esp_err_to_name(err)); goto exit; @@ -400,7 +402,11 @@ static int tee_sec_stg_encrypt(int argc, char **argv) char tag_hexstr[AES256_GCM_TAG_LEN * 2 + 1]; hexbuf_to_hexstr(tag, sizeof(tag), tag_hexstr, sizeof(tag_hexstr)); + char iv_hexstr[AES256_GCM_IV_LEN * 2 + 1]; + hexbuf_to_hexstr(iv, sizeof(iv), iv_hexstr, sizeof(iv_hexstr)); + ESP_LOGI(TAG, "Ciphertext -\n%s", ciphertext); + ESP_LOGI(TAG, "IV -\n%s", iv_hexstr); ESP_LOGI(TAG, "Tag -\n%s", tag_hexstr); free(plaintext_buf); @@ -431,6 +437,7 @@ void register_srv_sec_stg_encrypt(void) static struct { struct arg_str *key_str_id; struct arg_str *ciphertext; + struct arg_str *iv; struct arg_str *tag; struct arg_end *end; } tee_sec_stg_decrypt_args; @@ -446,6 +453,10 @@ static int tee_sec_stg_decrypt(int argc, char **argv) esp_err_t err = ESP_FAIL; const char *key_id = (const char *)tee_sec_stg_decrypt_args.key_str_id->sval[0]; + const char *iv_hexstr = tee_sec_stg_decrypt_args.iv->sval[0]; + uint8_t iv[AES256_GCM_IV_LEN]; + hexstr_to_hexbuf(iv_hexstr, strlen(iv_hexstr), iv, sizeof(iv)); + const char *tag_hexstr = tee_sec_stg_decrypt_args.tag->sval[0]; uint8_t tag[AES256_GCM_TAG_LEN]; hexstr_to_hexbuf(tag_hexstr, strlen(tag_hexstr), tag, sizeof(tag)); @@ -484,7 +495,7 @@ static int tee_sec_stg_decrypt(int argc, char **argv) .input_len = ciphertext_buf_len }; - err = esp_tee_sec_storage_aead_decrypt(&ctx, tag, sizeof(tag), plaintext_buf); + err = esp_tee_sec_storage_aead_decrypt(&ctx, iv, sizeof(iv), tag, sizeof(tag), plaintext_buf); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to decrypt data: %s", esp_err_to_name(err)); goto exit; @@ -511,8 +522,9 @@ void register_srv_sec_stg_decrypt(void) { tee_sec_stg_decrypt_args.key_str_id = arg_str1(NULL, NULL, "<key_id>", "TEE Secure storage key ID"); tee_sec_stg_decrypt_args.ciphertext = arg_str1(NULL, NULL, "<ciphertext>", "Ciphertext to be decrypted"); + tee_sec_stg_decrypt_args.iv = arg_str1(NULL, NULL, "<iv>", "AES-GCM initialization vector"); tee_sec_stg_decrypt_args.tag = arg_str1(NULL, NULL, "<tag>", "AES-GCM authentication tag"); - tee_sec_stg_decrypt_args.end = arg_end(3); + tee_sec_stg_decrypt_args.end = arg_end(4); const esp_console_cmd_t tee_sec_stg = { .command = "tee_sec_stg_decrypt", diff --git a/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py b/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py index 4f164b84ff..2acdcc3bf3 100644 --- a/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py +++ b/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py @@ -77,9 +77,10 @@ def test_tee_cli_secure_storage(dut: Dut) -> None: dut.write(f'tee_sec_stg_encrypt {sec_stg_key_ids.get(i)} {test_msg_hash}') test_msg_cipher = dut.expect(r'Ciphertext -\s*([0-9a-fA-F]{64})', timeout=30)[1].decode() + test_msg_iv = dut.expect(r'IV -\s*([0-9a-fA-F]{24})', timeout=30)[1].decode() test_msg_tag = dut.expect(r'Tag -\s*([0-9a-fA-F]{32})', timeout=30)[1].decode() - dut.write(f'tee_sec_stg_decrypt {sec_stg_key_ids.get(i)} {test_msg_cipher} {test_msg_tag}') + dut.write(f'tee_sec_stg_decrypt {sec_stg_key_ids.get(i)} {test_msg_cipher} {test_msg_iv} {test_msg_tag}') test_msg_decipher = dut.expect(r'Decrypted plaintext -\s*([0-9a-fA-F]{64})', timeout=30)[1].decode() assert test_msg_decipher == test_msg_hash 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 8fd3bd847c..4d8f2dcdf7 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 @@ -202,6 +202,7 @@ TEST_CASE("Test TEE Secure Storage - Encrypt-decrypt (aes256_gcm)", "[sec_storag TEST_ASSERT_NOT_NULL(decryptedtext); uint8_t tag[12]; + uint8_t iv[12]; uint8_t aad[16]; memset(aad, 0xA5, sizeof(aad)); @@ -227,11 +228,11 @@ TEST_CASE("Test TEE Secure Storage - Encrypt-decrypt (aes256_gcm)", "[sec_storag aead_ctx.input = plaintext; aead_ctx.input_len = SZ; - TEST_ESP_OK(esp_tee_sec_storage_aead_encrypt(&aead_ctx, tag, sizeof(tag), ciphertext)); + TEST_ESP_OK(esp_tee_sec_storage_aead_encrypt(&aead_ctx, iv, sizeof(iv), tag, sizeof(tag), ciphertext)); aead_ctx.input = ciphertext; aead_ctx.input_len = SZ; - TEST_ESP_OK(esp_tee_sec_storage_aead_decrypt(&aead_ctx, tag, sizeof(tag), decryptedtext)); + TEST_ESP_OK(esp_tee_sec_storage_aead_decrypt(&aead_ctx, iv, sizeof(iv), tag, sizeof(tag), decryptedtext)); TEST_ASSERT_EQUAL_HEX8_ARRAY(plaintext, decryptedtext, SZ); @@ -269,6 +270,7 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys", uint8_t *ciphertext = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); TEST_ASSERT_NOT_NULL(ciphertext); uint8_t tag[12]; + uint8_t iv[12]; uint8_t aad[16]; memset(aad, 0xA5, sizeof(aad)); @@ -285,7 +287,7 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys", esp_err_t err = esp_tee_sec_storage_clear_key(key_cfg.id); TEST_ASSERT_TRUE(err == ESP_OK || err == ESP_ERR_NOT_FOUND); TEST_ESP_OK(esp_tee_sec_storage_gen_key(&key_cfg)); - TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_tee_sec_storage_aead_encrypt(&aead_ctx, tag, sizeof(tag), ciphertext)); + TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_tee_sec_storage_aead_encrypt(&aead_ctx, iv, sizeof(iv), tag, sizeof(tag), ciphertext)); TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id)); @@ -300,7 +302,7 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys", TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id)); // Test with non-existent data - TEST_ESP_ERR(ESP_ERR_NVS_NOT_FOUND, esp_tee_sec_storage_aead_encrypt(&aead_ctx, tag, sizeof(tag), ciphertext)); + TEST_ESP_ERR(ESP_ERR_NVS_NOT_FOUND, esp_tee_sec_storage_aead_encrypt(&aead_ctx, iv, sizeof(iv), tag, sizeof(tag), ciphertext)); free(plaintext); free(ciphertext); @@ -309,7 +311,7 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys", TEST_CASE("Test TEE Secure Storage - Null Pointer and Zero Length", "[sec_storage]") { const char *key_id = "key_id_misc"; - uint8_t data[31], tag[12]; + uint8_t data[31], tag[12], iv[12]; esp_tee_sec_storage_key_cfg_t key_cfg = { .id = key_id, @@ -326,20 +328,24 @@ TEST_CASE("Test TEE Secure Storage - Null Pointer and Zero Length", "[sec_storag .input_len = sizeof(data), }; - TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_encrypt(&aead_ctx, NULL, sizeof(tag), data)); - TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_encrypt(&aead_ctx, tag, 0, data)); - TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_decrypt(&aead_ctx, NULL, sizeof(tag), data)); - TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_decrypt(&aead_ctx, tag, 0, data)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_encrypt(&aead_ctx, iv, sizeof(iv), NULL, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_encrypt(&aead_ctx, iv, sizeof(iv), tag, 0, data)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_encrypt(&aead_ctx, NULL, sizeof(iv), tag, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_encrypt(&aead_ctx, iv, 0, tag, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_decrypt(&aead_ctx, iv, sizeof(iv), NULL, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_decrypt(&aead_ctx, iv, sizeof(iv), tag, 0, data)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_decrypt(&aead_ctx, NULL, sizeof(iv), tag, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_decrypt(&aead_ctx, iv, 0, tag, sizeof(tag), data)); aead_ctx.input = NULL; aead_ctx.input_len = sizeof(data); - TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_encrypt(&aead_ctx, tag, sizeof(tag), data)); - TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_decrypt(&aead_ctx, tag, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_encrypt(&aead_ctx, iv, sizeof(iv), tag, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_aead_decrypt(&aead_ctx, iv, sizeof(iv), tag, sizeof(tag), data)); aead_ctx.input = data; aead_ctx.input_len = 0; - TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_encrypt(&aead_ctx, tag, sizeof(tag), data)); - TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_decrypt(&aead_ctx, tag, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_encrypt(&aead_ctx, iv, sizeof(iv), tag, sizeof(tag), data)); + TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_aead_decrypt(&aead_ctx, iv, sizeof(iv), tag, sizeof(tag), data)); TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_id)); @@ -385,6 +391,7 @@ static void test_aead_encrypt_decrypt(const char *key_id, const uint8_t *input, TEST_ASSERT_NOT_NULL(decrypted); uint8_t tag[12]; + uint8_t iv[12]; uint8_t aad[16]; esp_fill_random(aad, sizeof(aad)); @@ -396,11 +403,11 @@ static void test_aead_encrypt_decrypt(const char *key_id, const uint8_t *input, ctx.input = input; ctx.input_len = len; - TEST_ESP_OK(esp_tee_sec_storage_aead_encrypt(&ctx, tag, sizeof(tag), ciphertext)); + TEST_ESP_OK(esp_tee_sec_storage_aead_encrypt(&ctx, iv, sizeof(iv), tag, sizeof(tag), ciphertext)); ctx.input = ciphertext; ctx.input_len = len; - TEST_ESP_OK(esp_tee_sec_storage_aead_decrypt(&ctx, tag, sizeof(tag), decrypted)); + TEST_ESP_OK(esp_tee_sec_storage_aead_decrypt(&ctx, iv, sizeof(iv), tag, sizeof(tag), decrypted)); TEST_ASSERT_EQUAL_HEX8_ARRAY(input, decrypted, len); diff --git a/examples/security/tee/tee_secure_storage/README.md b/examples/security/tee/tee_secure_storage/README.md index a11d7a309e..73d5737af1 100644 --- a/examples/security/tee/tee_secure_storage/README.md +++ b/examples/security/tee/tee_secure_storage/README.md @@ -95,11 +95,13 @@ I (1001) Plaintext: 4c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f I (1001) Plaintext: 72 20 73 69 74 20 61 6d 65 74 2c 20 63 6f 6e 73 I (1011) Plaintext: 65 63 74 65 74 75 72 20 61 64 69 70 69 73 63 69 I (1021) Plaintext: 6e 67 20 65 6c 69 74 2e -I (1111) Encrypted data: 18 85 a2 97 7d 20 be 53 47 b7 3f 6f 52 06 8a 44 -I (1111) Encrypted data: 3b 7e 2e 25 7b 33 5d 4f 2a e5 17 5e bc d7 4e 23 -I (1111) Encrypted data: 2a 8f 89 a1 80 9c 6c 6b 00 e6 c6 39 7b 3f 75 65 -I (1121) Encrypted data: cd d5 f6 f6 3c 9a fb bb -I (1131) Tag: 6d 7f 1f 8e 1e a9 2c d9 d2 7f 9b db 16 cc 9b 68 +I (1111) Encrypted data: 5e b0 43 e9 38 a6 9c 04 85 00 be b2 d9 c7 40 08 +I (1111) Encrypted data: b1 ae 64 80 2b 91 72 8a 77 d6 3c b1 d5 7f ef 00 +I (1111) Encrypted data: 8d bc e0 c9 a9 9c d1 1f 33 76 34 2a da 02 a9 2f +I (1121) Encrypted data: d6 75 c1 3a 54 1b 84 ad +I (1131) IV: e8 f3 82 d8 bf 6d e5 4f 12 e0 51 57 +I (1131) Tag: 30 d4 c5 a1 73 9f 6d d2 3c de 83 cb 93 01 af b9 + I (1131) example_tee_sec_stg: Done with encryption/decryption! I (1141) main_task: Returned from app_main() ``` 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 094643249b..aebdf0e1c2 100644 --- a/examples/security/tee/tee_secure_storage/main/tee_main.c +++ b/examples/security/tee/tee_secure_storage/main/tee_main.c @@ -25,6 +25,7 @@ #define SHA256_DIGEST_SZ (32) #define ECDSA_SECP256R1_KEY_LEN (32) #define AES256_GCM_TAG_LEN (16) +#define AES256_GCM_IV_LEN (12) #define AES256_GCM_AAD_LEN (16) #define SIGN_KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_SIGN_KEY_STR_ID) @@ -165,6 +166,7 @@ static void example_tee_sec_stg_encrypt_decrypt(void *pvParameter) } uint8_t tag[AES256_GCM_TAG_LEN]; + uint8_t iv[AES256_GCM_IV_LEN]; uint8_t aad_buf[AES256_GCM_AAD_LEN]; memset(aad_buf, 0xA5, sizeof(aad_buf)); @@ -202,7 +204,7 @@ static void example_tee_sec_stg_encrypt_decrypt(void *pvParameter) ctx.input = (const uint8_t *)plaintext; ctx.input_len = plaintext_len; - err = esp_tee_sec_storage_aead_encrypt(&ctx, tag, sizeof(tag), ciphertext); + err = esp_tee_sec_storage_aead_encrypt(&ctx, iv, sizeof(iv), tag, sizeof(tag), ciphertext); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to encrypt data!"); goto exit; @@ -212,13 +214,14 @@ static void example_tee_sec_stg_encrypt_decrypt(void *pvParameter) ctx.input = (const uint8_t *)ciphertext; ctx.input_len = plaintext_len; - err = esp_tee_sec_storage_aead_decrypt(&ctx, tag, sizeof(tag), ciphertext); + err = esp_tee_sec_storage_aead_decrypt(&ctx, iv, sizeof(iv), tag, sizeof(tag), ciphertext); if (err != ESP_OK || memcmp(ciphertext, plaintext, plaintext_len) != 0) { ESP_LOGE(TAG, "Encryption verification failed!"); err = ESP_FAIL; goto exit; } + ESP_LOG_BUFFER_HEX("IV", iv, sizeof(iv)); ESP_LOG_BUFFER_HEX("Tag", tag, sizeof(tag)); ESP_LOGI(TAG, "Done with encryption/decryption!");