fix(esp_tee): prevent validation clobbering and deref-before-check

TEE secure-service handlers had two bugs letting REE bypass
pointer-region validation:

1. valid_addr = instead of valid_addr &= in AEAD encrypt/decrypt
   and DS sign handlers, clobbering prior failed checks.
   Impact: REE writes to TEE DRAM via DS signature output, or reads
   TEE DRAM via AEAD output.

2. data->rsa_length dereferenced before data is validated in DS sign
   and DS start_sign handlers.

Fix: use &= for subsequent checks, add early return after initial
data pointer check in DS handlers.
This commit is contained in:
Aditya Patwardhan
2026-04-14 14:41:59 +05:30
parent 1735ec860d
commit 2de0ed6a2b
2 changed files with 12 additions and 4 deletions
@@ -392,8 +392,12 @@ esp_err_t _ss_esp_ds_sign(const void *message,
void *signature)
{
bool valid_addr = esp_tee_buf_in_ree(data, sizeof(esp_ds_data_t));
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
size_t n = get_ds_msg_sign_len(data->rsa_length);
valid_addr = (n > 0) && esp_tee_buf_in_ree(message, n) && esp_tee_buf_in_ree(signature, n);
valid_addr &= (n > 0) && esp_tee_buf_in_ree(message, n) && esp_tee_buf_in_ree(signature, n);
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
valid_addr &= (key_id != (hmac_key_id_t)CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID);
@@ -415,8 +419,12 @@ esp_err_t _ss_esp_ds_start_sign(const void *message,
{
bool valid_addr = (esp_tee_buf_in_ree(esp_ds_ctx, sizeof(esp_ds_context_t *)) &&
esp_tee_buf_in_ree(data, sizeof(esp_ds_data_t)));
if (!valid_addr) {
return ESP_ERR_INVALID_ARG;
}
size_t n = get_ds_msg_sign_len(data->rsa_length);
valid_addr = (n > 0) && esp_tee_buf_in_ree(message, n);
valid_addr &= (n > 0) && esp_tee_buf_in_ree(message, n);
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
valid_addr &= (key_id != (hmac_key_id_t)CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID);
@@ -176,7 +176,7 @@ esp_err_t _ss_esp_tee_sec_storage_aead_encrypt(const esp_tee_sec_storage_aead_ct
esp_tee_buf_in_ree(output, ctx->input_len));
if (ctx->aad_len != 0) {
valid_addr = esp_tee_buf_in_ree(ctx->aad, ctx->aad_len);
valid_addr &= esp_tee_buf_in_ree(ctx->aad, ctx->aad_len);
}
if (!valid_addr) {
@@ -196,7 +196,7 @@ esp_err_t _ss_esp_tee_sec_storage_aead_decrypt(const esp_tee_sec_storage_aead_ct
esp_tee_buf_in_ree(output, ctx->input_len));
if (ctx->aad_len != 0) {
valid_addr = esp_tee_buf_in_ree(ctx->aad, ctx->aad_len);
valid_addr &= esp_tee_buf_in_ree(ctx->aad, ctx->aad_len);
}
if (!valid_addr) {