Differential Fault Analysis on AES-128 with Jean Grey

In this post we will use clock glitches to attack AES using simple Differential Fault Analysis and Jean Gray library available on GitHub.

DFA is based on faults injected by an attacker into the device. It allows to recover some information about the secret from the target of the attack. Those faults can be injected in many ways. One of them is glitching hardware that performs some security operations. In the previous post about glitching we discussed how to jump out of a simple loop and break RSA-CRT using the glitch.

In this post we use ChipWhisperer to perform DFA based on a fault attack on AES. To recall: AES-128 works on a byte matrix 4×4 called state. It performs 10 rounds in which bytes are substituted, shifted across rows, mixed within columns and XORed with round keys. The attack relies on inducing a fault that propagates on all the bytes of the state. Let’s see what happens if we inject a fault on the first byte of the state:

Error propagation

If the first byte is faulty, then the error is propagated to the whole column after MixColumns procedure and then shifted in ShiftRows procedure. In the next round MixColumns procedure the error is spread all over the state. In this case we omit SubBytes and AddRoundKey, because they have nothing to do with error (fault) propagation.

The key idea here is that if one byte is faulty, then after two MixColumns procedures all bytes are faulty. It is possible to inject faults in other moments of the execution with the same effect. The only condition we need to care about in practice is that the device cannot crash.

Now, having all those faults, the algorithm produces an incorrect ciphertext. For the attack we also need one ciphertext that is produced correctly.

Although the theoretical approach described above is fully applicable, we chose to do it in another way. We still produce one fault that propagates on all the bytes of the state, but we do it in 8th round during MixColumns:

/* mixColums */
for(i=0; i<4; ++i){
if(i==3 && trigger) {
trig_hi();
}
t = tmp[4*i+0] ^ tmp[4*i+1] ^ tmp[4*i+2] ^ tmp[4*i+3];
state->s[4*i+0] =
GF256MUL_2(tmp[4*i+0]^tmp[4*i+1])
^ tmp[4*i+0]
^ t;
state->s[4*i+1] =
GF256MUL_2(tmp[4*i+1]^tmp[4*i+2])
^ tmp[4*i+1]
^ t;
state->s[4*i+2] =
GF256MUL_2(tmp[4*i+2]^tmp[4*i+3])
^ tmp[4*i+2]
^ t;
state->s[4*i+3] =
GF256MUL_2(tmp[4*i+3]^tmp[4*i+0])
^ tmp[4*i+3]
^ t;
}

Our goal is to glitch variable t. If we succeed, the whole column is faulty and the fault propagates on the entire state in the next MixColumns. It seems easier than inducing a fault at the beginning of the 8th round and works well in practice. Let’s see some executions of the algorithm on XMEGA with parameters:

txi: 74657374746573747465737474657374 (plaintext)
key: 2B7E151628AED2A6ABF7158809CF4F3C

We try different parameters for glitch (function setup) which gives the following results:

Now, having the results we let Jean Grey do the job. It is a part of Side-Channel Marvels – a library dedicated to perform side-channel analyses (among other side-channel related things). The actual DFA for AES is implemented in a tool phoenixAES.

What we need to do is provide the correct ciphertext in the first line, then a couple of faulted ciphertexts. Two faulty ciphertexts are enough to recover the last round key.

The actual analysis can be performed in a couple different ways, but the core idea is the following: for every 4 bytes of the last round key we solve a system of 4 equations with five variables that can look like this:

After brute-force solving the system of equations we get some small set of possible values for the key. Having a couple of ciphertexts the last round key can be unambiguously determined. For more details on the analysis you can look at the paper with the attack.

Another tool from Side-Channel Marvels comes in handy here: Stark can recover the secret key from the last round key which turns our correct:

The Jupyter notebook and source code for this post can be found in our repository.

Leave a Reply

Close Menu