Fault Injection
Fault Injection¶
Glitching software
Generic Side-Channel and Fault Injection simulator
ChipWhisperer¶
ChipWhisperer is an Open-source software, hardware, for Fault Injection on embedded systems.
Interactive ChipWhisperer tutorials using Jupyter notebooks.
https://learn.chipwhisperer.io/courses/power-analysis-101
Clock Fault Injection¶
Power/Voltage Fault Injection¶
Controlling the Program Counter¶
Instruction Corruption:
MOV R0, R1 1110000110100000000000000000001
MOV R0, R2 1110000110100000000000000000010
MOV R0, R1 1110000110100000000000000000001
STR R7, [R7, #16] 1110000110001001011100000010000
Instruction Skipping:
MOV R0, R1 1110000110100000000000000000001
MOV R1, R1 1110000110100000000100000000001
Controlling the PC using LDR:
LDR R3, [R1], #4 1110010010010000100110000000100
LDR PC, [R1], #4 1110010010010000111110000000100
Controlling the PC using LDMIA:
LDMIA R1!, {r3,r10} 11101000101100010000011111111000
LDMIA R1!, {r3,r10,pc} 11101000101100011000011111111000
RSA Fault Injection¶
Injecting a fault on the correct place
Using fault injection with RSA on known input and output with the public key provides information needed to recover the private key
RSA Signature Example¶
Math Breakdown:
Countermeasures¶
Double Checking:
short pin_check(byte* buffer) {
if (pin_ctr > 0){
pin_ctr--;
if (array_compare(pin, buffer, 4) == 0) { // PIN ok at first check
if (array_compare(pin, buffer, 4) != 0) {
auth = FALSE; // PIN not ok at second check
return 0x6986;
}
else { // PIN Ok
auth = TRUE;
...
}
}
else {
...
}
}
}
Verify Signatures:
short pin_check(byte* buffer) {
sign(buffer, signature);
if (verify(buffer, signature)){
auth = TRUE; // signature verification success
send(signature); // send signature
return 0x9000; // report success
}
else {
auth = FALSE; // signature verification fail
return 0x6986 // no signature transmission
}
}
Traps:
byte result = SOME_VALUE;
byte resultChecksum = ~SOME_VALUE;
...
if ((result ^ resultChecksum) != 0xFF){
fail(); //verify checksum
}
Random Delay:
short pin_check(byte* buffer) {
// get random number in range 0..255
int rnd = get_random(255);
while (rnd > 0 ) {
rnd--; // Random Delay
}
if (pin_ctr > 0){
pin_ctr--;
if ( array_compare(pin, buffer, 4) == 0){
}
}
}
AES Differential Fault Attack¶
- Faults in the same column are non-distinguishable
Round 9 Fault injection:
Injecting a fault in a random byte at the beginning of the 9th Mix Columns operation propagates through the shift row in round 10.
This means that one injection can effect 4 output bytes. Using the correct AES with the faulty AES output can decrease the key size from 32 bits to 8 bits
Round 8 Fault Injection:
Injecting a fault in a random byte at the beginning of the 8th Mix Columns operation propagates through the shift rows in round 9.
This fault then also propagates through the mix columns in the 9th round and the shift row in the 10th round.
With one correct and one fault pair with a 32-bit brute force it is possible to recover a 128 bit key.
Single fault Disadvantages¶
Fault location must be known if not the search space multiplies
- Unknown byte multiplies search space by 4
- Unknown round multiplies search space by 10
- Unknown operation hit messes up the key search
- 32-bit AES key takes 20 mins
Injection Tricks¶
- Hit the Key Addition, Substitute, shift row or mix columns
- Check that exactly 4 output bytes have been changed.
- With every element in the same column there is overlapping faults
Fault injection in automotive diagnostic protocols¶
https://www.riscure.com/publication/fault-injection-automotive-diagnostic-protocols/
Software Fault Injection¶
- Undervolting and Overvolting is possible through software.
- This is done by setting a register.
- This makes it set over all of the cores and triggers bit flips
Row Hammer¶
Accessing ROW 1 in RAM then row 3 multiple times may make row 2 bits flip.