Riscure Whitepaper Fault Mitigation Patterns Final
Riscure Whitepaper Fault Mitigation Patterns Final
Abstract
Hardware Fault Attacks can break software security by revealing secrets during program execution
or a change of the behavior of a program. Without profound knowledge of these attacks, it is hard
to defend code effectively. Fault resistance requires pervasive protection throughout the code. This
paper introduces a collection of secure programming patterns for security-critical devices. These
patterns help developers to mitigate the risk of fault injection in a cost-effective way.
1. Introduction
Hardware Fault Injection is a class of hardware security attacks which have become increasingly
popular, as these attacks are powerful and have a high probability of success. Most devices today
are completely vulnerable against these attacks as developers have little awareness of the threat,
and do not know how to protect their code. The software security implications of these attacks are
discussed in [1].
Fortunately, it is possible to harden the software and mitigate the Fault Injection threat. However,
since the number of attacker opportunities is very high this could require a large effort. In this
paper, we propose a set of 11 fault mitigation patterns. These patterns have the advantage that
they can be repeatedly applied, without making a detailed design for each instance, and thus
minimize the mitigation effort. We organize the patterns along with three main strategies:
1. Resist: increase code resistance so that faults are less likely to disturb program behavior;
2. Recover: code resilience to prevent insecure behavior following a fault;
3. Respond: actions to deter attackers after detecting a fault.
It is our experience that these patterns, if well understood, are applied efficiently at the average
cost of 12 minutes per instance. Furthermore, there is typically no need to protect the entire code
base: protecting the critical code is often good enough.
2. Resist
An attacker using fault injection aims for a specific effect, e.g. changing a value or decision.
Resistance is introduced by making useful values hard to achieve, or by making it hard to find the
right timing to manipulate a decision.
Pattern 1. FAULT.CONSTANT.CODING
Problem Sensitive data carrying a limited set of values (like phase and state variables) is
manipulated by fault injection attacks if they use trivial constant coding (e.g. 0, 1,
0xFF, or -1).
Solution Do not use trivial constants for sensitive data. These constants should use non-
trivial values with the maximal hamming distance that is unlikely to be set through
fault injection. This includes avoiding booleans which are coded in a trivial way (0 /
1). Use complex symbolic constants instead.
Pattern 2. FAULT.RANDOM.DELAY
3. Recover
Even when fault injection is successful, it is possible to make resilient code that would continue
correct execution and prevent exploitation. This includes double-checking to verify value
correctness and crypto results, but also double-checking conditional statements, branches, loops,
and program flow.
Pattern 3. FAULT.VALUE.CHECK
Problem Sensitive data is manipulated by a fault injection attack at any time during
program execution.
Solution Verify sensitive data. Sensitive data can, for instance, be protected by a checksum.
Data protected in this way should be verified at regular intervals. Ideally, the
integrity of sensitive data should be verified each time when used.
Problem Cryptographic algorithms are sensitive to fault injection. They may even reveal key
data through the output of false encryptions due to fault injection. Differential
fault analysis (DFA) is a technique for this.
Solution Check for fault injection during or after crypto. Verify any ciphered data before
transmission by deciphering or repeated enciphering. If the deciphered data
matches the original input, or the repeated enciphering matches the original
output, it is most likely that the encryption was not corrupted.
Pattern 5. FAULT.DECISION.CHECK
Problem Sensitive data is manipulated by fault injection attacks. When a decision is made
upon a single test the decision may be corrupted.
Solution Double-check sensitive conditions. A conditional process based on sensitive data
should double-check the data. Preferably, these checks should not be identical,
but complementary, as the attacker will have to perform two different types of
attack. In addition, the checks should be temporally separated to reduce the risk
of a single multi-cycle glitch bypasses check and double-check.
Pattern 6. FAULT.BRANCH.CHECK
Pattern 7. FAULT.LOOP.CHECK
Problem Repetitive processes running in a loop are terminated early by a fault injection
attack.
Solution Verify loop completion, avoid early or late completion.
Pattern 8. FAULT.NESTED.CHECK
Problem Function calls may be skipped by a fault, and render all included checks useless.
Solution Verification and protected functionality should be at the same nest level.
Problem Fault injection can hit the program counter or stack. This can result in
“code hijacking”, i.e. unauthorized jumps to privileged code. Verification
of the correct flow should be done during the execution of sensitive
code.
Solution Use a counter to keep track of the correctness of the execution path.
Check the counter to verify the completion of the execution path.
Prevent separate paths reaching identical counter values by stepping
with prime numbers.
4. Respond
Immunity is hard. Especially when so many vulnerabilities exist. It is therefore important to detect
fault attempts and act accordingly.
Problem Immunity against fault injection is hard, especially given the widespread
nature of the problem. Attackers will therefore be inclined to repeat
fault experiments and keep trying to find an exploitable weakness.
Solution By the introduction of a penalty, it is possible to deter attackers and
reduce their chance of success. Such a penalty can be in slowing down
the system or disabling functionality. The disabling functionality can be
temporary (e.g. require service center intervention), or permanent
(termination or key zeroing).
5. Conclusion
Fault Injection is a growing threat to devices that need to be secure in the field. Since the amount of
FI vulnerabilities in software is overwhelming, there is a need for a systematic mitigation approach.
We propose to use Fault Mitigation Patters, a set of 11 countermeasures that can be applied
throughout the code, and require little adaption for repeated application.
6. Reference
[1] Bilgiday Yuce, Patrick Schaumont, Marc Witteman, Fault Attacks on Secure Embedded Software:
Threats, Design and Evaluation, https://arxiv.org/pdf/2003.10513.pdf
Riscure China
Room 2030-31, No. 989, Changle Road, Shanghai
200031
China
Phone: +86 21 5117 5435
mailto:[email protected]
Riscure China
Room 2030-31, No. 989, Changle Road, Shanghai
200031
China
Phone: +86 21 5117 5435
11 Fault Mitigation Patterns | Riscure | www.riscure.com
[email protected]