ESP_FAULT_ASSERT macro
Assert a condition is true, in a way that should be resistant to fault injection for single fault attacks. - 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. - If CONDITION is ever false, a system reset is triggered.
Syntax
#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(); \
} while(0)
Arguments
CONDITION
A condition which will evaluate true unless an attacker used fault injection to skip or corrupt some other critical system calculation.
Notes
Place this macro after a "normal" check of CONDITION that will fail with a normal error message. This is the fallback in case a fault injection attack skips or corrupts the result of that check. (Although ensure that an attacker can't use fault injection to skip past the "normal" error message, to avoid this check entirely.) This macro increases binary size and is slow and should be used sparingly. This macro does not guarantee fault injection resistance. In particular CONDITION must be chosen carefully - a fault injection attack which sets CONDITION to true will not be detected by this macro. Care must also be taken that an attacker can't use a fault to completely bypass calling whatever function tests ESP_FAULT_ASSERT. This is difficult to debug as a failure triggers an instant software reset, and UART output is often truncated (as FIFO is not flushed). Define the ESP_FAULT_ASSERT_DEBUG macro to debug any failures of this macro due to software bugs.