fix(esp_common/esp_fault): make ESP_FAULT_ASSERT survive optimization

ESP_FAULT_ASSERT(C) was silently deleted by the optimizer when C is a cached
flag/status already proven by a preceding `if (!C) return/goto`: the compiler
folds C to a constant and drops all three checks, removing the fault-injection
protection with no warning.
This commit is contained in:
harshal.patil
2026-06-22 11:20:04 +05:30
parent bfb6b4a2b2
commit 024de60208
11 changed files with 45 additions and 24 deletions
@@ -3,11 +3,12 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include "sdkconfig.h"
#include "esp_rom_sys.h"
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
@@ -19,6 +20,10 @@ extern "C" {
* - Expands CONDITION multiple times (condition must have no side effects)
* - Compiler is told all registers are invalid before evaluating CONDITION each time, to avoid a fault
* causing a misread of a register used in all three evaluations of CONDITION.
* - The result of each evaluation is stored into a volatile variable and re-read before the branch.
* This prevents the compiler from constant-folding CONDITION and deleting the whole check when it
* has already proven the value - e.g. when this macro follows a normal "if (!cond) { ... }" check
* of the same value, which would otherwise silently remove the fault-injection protection.
* - If CONDITION is ever false, a system reset is triggered.
*
* @note Place this macro after a "normal" check of CONDITION that will fail with a normal error
@@ -40,13 +45,20 @@ extern "C" {
* @param CONDITION A condition which will evaluate true unless an attacker used fault injection to skip or corrupt some other critical system calculation.
*
*/
#define ESP_FAULT_ASSERT(CONDITION) do { \
asm volatile ("" ::: "memory"); \
if(!(CONDITION)) _ESP_FAULT_RESET(); \
asm volatile ("" ::: "memory"); \
if(!(CONDITION)) _ESP_FAULT_RESET(); \
asm volatile ("" ::: "memory"); \
if(!(CONDITION)) _ESP_FAULT_RESET(); \
#define ESP_FAULT_ASSERT(CONDITION) do { \
bool esp_fault_assert_chk; \
asm volatile ("" ::: "memory"); \
esp_fault_assert_chk = (CONDITION); \
asm volatile ("" : "+r"(esp_fault_assert_chk)); \
if(!esp_fault_assert_chk) _ESP_FAULT_RESET(); \
asm volatile ("" ::: "memory"); \
esp_fault_assert_chk = (CONDITION); \
asm volatile ("" : "+r"(esp_fault_assert_chk)); \
if(!esp_fault_assert_chk) _ESP_FAULT_RESET(); \
asm volatile ("" ::: "memory"); \
esp_fault_assert_chk = (CONDITION); \
asm volatile ("" : "+r"(esp_fault_assert_chk)); \
if(!esp_fault_assert_chk) _ESP_FAULT_RESET(); \
} while(0)
#if CONFIG_IDF_TARGET_ARCH_XTENSA
@@ -5,3 +5,4 @@ components/esp_security/test_apps/crypto_drivers:
- if: ((SOC_HMAC_SUPPORTED == 1) or (SOC_DIG_SIGN_SUPPORTED == 1)) or (SOC_KEY_MANAGER_SUPPORTED == 1)
depends_components:
- esp_security
- esp_hal_security
@@ -1,3 +1,3 @@
# Increasing TEE DRAM size
# 17.5KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x4600
# Increasing TEE IRAM size
# 38KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x9800
@@ -4,7 +4,7 @@ CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
# Reducing TEE I/DRAM sizes
# 24KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x6000
CONFIG_SECURE_TEE_IRAM_SIZE=0x7000
# 13KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x3400
@@ -1,6 +1,6 @@
# Reducing TEE IRAM size
# 30KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x7800
CONFIG_SECURE_TEE_IRAM_SIZE=0x8800
# TEE Secure Storage: Release mode
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
@@ -1,3 +1,12 @@
# NOTE: This sdkconfig is intended solely for CI build purposes - to verify ESP-TEE
# builds across various configurations - and is not intended for production use.
# Increasing TEE I/DRAM sizes
# 38KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x9800
# 18KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x4800
# Security features - build-only configuration
CONFIG_PARTITION_TABLE_OFFSET=0xf000
@@ -13,9 +22,3 @@ CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=y
# TEE Secure Storage: Release mode
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
# Increasing TEE I/DRAM size
# 34KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x8800
# 18KB
CONFIG_SECURE_TEE_DRAM_SIZE=0x4800
@@ -15,3 +15,7 @@ CONFIG_SECURE_TEE_ATT_KEY_STR_ID="tee_att_keyN"
# Enabling flash protection over SPI1
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=y
# Increasing TEE IRAM size
# 38KB
CONFIG_SECURE_TEE_IRAM_SIZE=0x9800
@@ -1,5 +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, 0x9000, 0x6000,
factory, 0, 0, 0x10000, 1M
nvs, data, nvs, , 0x6000,
factory, 0, 0, , 1M
flash_test, data, fat, , 528K
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
3 nvs, data, nvs, 0x9000, 0x6000, nvs, data, nvs, , 0x6000,
4 factory, 0, 0, 0x10000, 1M factory, 0, 0, , 1M
5 flash_test, data, fat, , 528K
@@ -1,4 +1,5 @@
CONFIG_ESP_TASK_WDT_EN=n
CONFIG_PARTITION_TABLE_OFFSET=0X9000
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_SECURE_FLASH_ENC_ENABLED=y