From 4751d66bd060549349e5bac695a154a158a59a65 Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Mon, 6 Jul 2026 17:28:11 +0800 Subject: [PATCH] fix(esp_tee): guard calloc overflow and attestation leak --- .../components/attestation/esp_att_utils_crypto.c | 14 +++++++++++++- .../esp_tee/subproject/main/common/multi_heap.c | 10 ++++++++-- components/mbedtls/port/aes/esp_aes_gcm.c | 4 ++++ 3 files changed, 25 insertions(+), 3 deletions(-) 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..ad0a9a9c589 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 @@ -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 */ @@ -302,6 +302,11 @@ esp_err_t esp_att_utils_ecdsa_get_sign(const esp_att_ecdsa_keypair_t *keypair, c return ESP_ERR_INVALID_SIZE; } + /* Initialise the out-params up front so the error path at 'exit' can free them safely even + * when we bail out (e.g. signature generation fails) before they are allocated. */ + *sign_r_hexstr = NULL; + *sign_s_hexstr = NULL; + esp_err_t err = ESP_FAIL; unsigned char sign_r[SECP256R1_ECDSA_KEY_LEN] = {0}, sign_s[SECP256R1_ECDSA_KEY_LEN] = {0}; @@ -340,5 +345,12 @@ esp_err_t esp_att_utils_ecdsa_get_sign(const esp_att_ecdsa_keypair_t *keypair, c err = ESP_OK; exit: + if (err != ESP_OK) { + /* free(NULL) is a no-op, so this is safe whether or not the buffers were allocated. */ + free(*sign_r_hexstr); + *sign_r_hexstr = NULL; + free(*sign_s_hexstr); + *sign_s_hexstr = NULL; + } return err; } diff --git a/components/esp_tee/subproject/main/common/multi_heap.c b/components/esp_tee/subproject/main/common/multi_heap.c index cceb600052d..ade9f35f759 100644 --- a/components/esp_tee/subproject/main/common/multi_heap.c +++ b/components/esp_tee/subproject/main/common/multi_heap.c @@ -107,7 +107,10 @@ void *esp_tee_heap_malloc(size_t size) void *esp_tee_heap_calloc(size_t n, size_t size) { - size_t reg_size = n * size; + size_t reg_size; + if (__builtin_mul_overflow(n, size, ®_size)) { + return NULL; + } void *ptr = esp_tee_heap_malloc(reg_size); if (ptr != NULL) { memset(ptr, 0x00, reg_size); @@ -241,7 +244,10 @@ void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps) void *heap_caps_aligned_calloc(size_t alignment, size_t n, size_t size, uint32_t caps) { (void) caps; - uint32_t reg_size = n * size; + size_t reg_size; + if (__builtin_mul_overflow(n, size, ®_size)) { + return NULL; + } void *ptr = esp_tee_heap_aligned_alloc(reg_size, alignment); if (ptr != NULL) { diff --git a/components/mbedtls/port/aes/esp_aes_gcm.c b/components/mbedtls/port/aes/esp_aes_gcm.c index 9e5ac70aa04..636ba5f9746 100644 --- a/components/mbedtls/port/aes/esp_aes_gcm.c +++ b/components/mbedtls/port/aes/esp_aes_gcm.c @@ -582,6 +582,10 @@ int esp_aes_gcm_finish( esp_gcm_context *ctx, uint8_t len_block[AES_BLOCK_BYTES] = {0}; uint8_t stream[AES_BLOCK_BYTES] = {0}; + (void)output; + (void)output_size; + *output_length = 0; + if ( tag_len > 16 || tag_len < 4 ) { return ( MBEDTLS_ERR_GCM_BAD_INPUT ); }