From 53d6c28d3ff42d1a5489750eb6203cee38e6f463 Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Mon, 6 Jul 2026 16:33:26 +0800 Subject: [PATCH] fix(esp_tee): fixes IV length check for TEE AEAD operations --- .../include/esp_tee_sec_storage.h | 12 ++++++++++-- .../tee_sec_storage/tee_sec_storage.c | 18 ++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) 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 a889a865ca6..d8c0d36a2f5 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 @@ -141,10 +141,14 @@ 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; must be exactly 12 bytes (96-bit IV, per NIST SP 800-38D) * @param[out] tag Pointer to the authentication tag buffer - * @param[in] tag_len Length of the authentication tag + * @param[in] tag_len Length of the authentication tag; must be 12 to 16 bytes (96- to 128-bit tag, per NIST SP 800-38D) * @param[out] output Pointer to the output data buffer * + * @note Non-standard @p iv_len / @p tag_len values are rejected with ESP_ERR_INVALID_SIZE. + * * @return esp_err_t ESP_OK on success, appropriate error code otherwise. */ esp_err_t esp_tee_sec_storage_aead_encrypt(esp_tee_sec_storage_aead_ctx_t *ctx, uint8_t *tag, size_t tag_len, uint8_t *output); @@ -153,10 +157,14 @@ esp_err_t esp_tee_sec_storage_aead_encrypt(esp_tee_sec_storage_aead_ctx_t *ctx, * @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; must be exactly 12 bytes (96-bit IV, per NIST SP 800-38D) * @param[in] tag Pointer to the authentication tag buffer - * @param[in] tag_len Length of the authentication tag + * @param[in] tag_len Length of the authentication tag; must be 12 to 16 bytes (96- to 128-bit tag, per NIST SP 800-38D) * @param[out] output Pointer to the output data buffer * + * @note Non-standard @p iv_len / @p tag_len values are rejected with ESP_ERR_INVALID_SIZE. + * * @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); 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 7704ad1663d..f2720957921 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 @@ -35,8 +35,10 @@ #define AES256_KEY_LEN 32 #define AES256_KEY_BITS (AES256_KEY_LEN * 8) -#define AES256_DEFAULT_IV_LEN 16 -#define AES256_GCM_IV_LEN (AES_GCM_SUPPORTED_IV_LEN) +#define AES256_GCM_IV_LEN 12 +#define AES256_GCM_TAG_LEN_MIN 12 /* NIST SP800-38D general-use minimum (96-bit tag) */ +#define AES256_GCM_TAG_LEN_MAX 16 /* full GCM tag (128-bit) */ +#define ECDSA_SECP384R1_KEY_LEN 48 #define ECDSA_SECP256R1_KEY_LEN 32 #define ECDSA_SECP192R1_KEY_LEN 24 @@ -558,8 +560,16 @@ static esp_err_t tee_sec_storage_crypt_common(const char *key_id, const uint8_t return ESP_ERR_INVALID_ARG; } - if (len == 0 || tag_len == 0 || iv_len != AES256_GCM_IV_LEN) { - ESP_LOGE(TAG, "Invalid input/tag/iv length"); + if (len == 0) { + ESP_LOGE(TAG, "Invalid input length"); + return ESP_ERR_INVALID_SIZE; + } + + /* Enforce standard AES-GCM parameters */ + if (iv_len != AES256_GCM_IV_LEN || + tag_len < AES256_GCM_TAG_LEN_MIN || tag_len > AES256_GCM_TAG_LEN_MAX) { + ESP_LOGE(TAG, "Non-standard GCM iv_len(%u)/tag_len(%u) rejected", + (unsigned)iv_len, (unsigned)tag_len); return ESP_ERR_INVALID_SIZE; }