-
Notifications
You must be signed in to change notification settings - Fork 51
Description
When programming to protect against fault-injections (E.g: glitching, voltage spikes, lasers), it is common to introduce multiple checks, which unfortunately can be removed by the compiler for obvious optimization reasons.
When the compiler sees two consecutive tests that are exactly identical and have no observable side effects, it applies an optimization known as common subexpression elimination (CSE): the second reading of the same value is removed and the second if statement becomes a simple conditional jump that will never be executed separately.
In a fault injection context, we want each test to be actually executed; otherwise, the attacker could corrupt the first read and the program would still pass the check.
To prevent this kind behavior, an observable side effect must be introduced between the two readings, or the compiler must be explicitly told that the read value can change “externally.” Here are the most common techniques in Rust that should addressed :
- Read the data using volatile access ( https://doc.rust-lang.org/std/ptr/fn.read_volatile.html) (unsafe of course)
- Use Atomics with strict ordering SeqCst (https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html)
- ASM inline (can be architecture dependent)
EDIT: Blackboxes removed as discussed below.