Introduction to glitching

In this post we will describe another type of attack in the area of power analysis – glitch attack. We’ll try to explain how it works, why it’s not that easy and certainly not that repeatable.

There are two types of glitch attacks we’ll cover – clock glitch and power glitch. In this and a couple of future posts we’ll focus on clock glitches.

In a chip a clock cycle is a period between two adjacent pulses of the oscillator. Usually it starts on a raising edge. In this period the chip usually executes some instructions. Some instructions require one clock cycle, some more, sometimes a few instructions are executed during one clock cycle.

Instructions are executed by multiple logic gates that respond to the voltage change and the outputs depend on the voltage on binary inputs – high or low. If there is at some point in a clock cycle change on a binary input, the output will differ from the expected. Such situation would look like this:

Clock cycle

But what is the point of making such alterations? Well, glitch attacks can be very powerful. Let’s look at the example with simple password – comparing provided password with the correct one:


unsigned c = 1;
for(int i =0;i<N;i++){
if(p[i]!=q[i]) {
c = 0;
break;
}
}
if(c) {
my_puts("Pass");
}
else {
my_puts("Fail");
}

Imagine a situation when we can alter a specific instruction in that loop that’s responsible for checking if the loop condition is true. If we cause such a change in a first iteration, we’ll get “Pass” without checking the password!

Ok, but how exactly we can force this change in the voltage? Luckily for us, the capture board from ChipWhisperer can generate its clock signal with glitch. It’s actually the first type of glitch we mentioned in the intro – clock glitch. XOR operation is performed on input clock and glitch and passed to the device under test (in this case it’s XMEGA).

Unfortunately there are a couple of difficulties one must face when glitching.

Firstly, glitch can make the chip stop responding, however it is safe for the device. It can make process of glitching really annoying because sometimes it requires resetting the device manually (although resetting programmatically is possible, sometimes it doesn’t work). We’ve come up with a workaround which we’ll address in future posts.

Secondly, finding right parameters for the glitch can be a very long process, because it depends on many fine adjustments. Even when the right parameters are finally found, it doesn’t guarantee that they’ll work every single time.

Now, there are a few parameters for the clock glitch we need to set. They are:

  1. Offset – (in percents of clock cycle period) – it tells the capture board where to insert the glitch after (positive value) or before (negative value) the rising edge.
  2. Width – (in percents of clock cycle period) – it tells the capture board about the width of the glitch – positive values describe the width from point indicated by offset to the right, negative to the left.
  3. Repeat – the number of times we want to repeat the glitch (in consecutive clock cycles)
  4. Manual/external – we can trigger the glitch manually from python code (manual) or externally (from the point of view of the capture board), hard-coded in a program. The second one is much more precise and can be used in cases when we want to hit some specific instruction.
  5. External offset – the number of cycles after the glitch will be made in case of external glitching.

Now it’s time for some examples. Firstly, we’ll try to find parameters for a manual glitch on a simple infinite loop:

volatile uint8_t a = 0;

putch('A');

while(a != 2){
;
}

Our goal is to leave the loop. Let’s look at the actual instructions:

while(a != 2){
460: 89 81 ldd r24, Y+1 ; 0x01
462: 82 30 cpi r24, 0x02 ; 2
464: e9 f7 brne .-6 ; 0x460
;
}

Here we have three instructions – loading the value of a to some register, comparing it with 2 and a conditional jump to the beginning of the loop. If we disturb any of them, we can expect that the program will leave the loop.

We want to know when it happens, so we put

led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);

uart_puts("1234");

led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);
led_error(1);

so we can notice when it happens – we should see message 1234 from the device.

We are looking for a successful glitch in:

width_range = Range(-10, 10, 1)
offset_range = Range(-10, 10, 1)

Both for offset and width from -10% to 10% (only integers). We were able to find a few couples of working parameters, for example width = 3 and offset = -8:

We applied the same parameters and repeated the trial:

We can observe that besides the behavior we expect there are other outputs from the device. Glitching is not entirely predictable and repeatable, sometimes NOT crashing the target and obtaining SOME result is a success.

However, there are some attacks that are possible to reproduce. One of them is Bellcore attack on RSA CRT, based on 2001 paper from Journal of Cryptology.

The computational cost of performing exponentiation in RSA using Chinese Reminder Theorem can be approximately four times smaller comparing to the computational cost of the traditional exponentiation modulo N. However, if no countermeasures are applied, RSA CRT is very prone to an attack that results in discovering factors of N= pq.

During RSA CRT two operations of exponentiation are performed:

S_1 = x^(d mod p-1) mod p
S_2 = x^(d mod q-1) mod q

And then signature S is created as:

S = a * S_1 + b * S_2 mod N

For some a,b. Let’s assume (without the loss of generality) that S_1 is faulty, then we get a faulty signature S’ and the following statement holds:

gcd(S-S',N) = q

Which can be easily checked.

Out task is then to produce faulty signature. Firstly, we hard-code some parameters of RSA:

p  = 23;
q = 17;
e = 3;
c = 230;

For those parameters the signature (or simply decryption of c) is 253 (0xFD).

We use the external glitch during the computations, which means that the catpure board will produce glitched clock signal after trigger_high():

trigger_high();
T m1 = Xpow(c, dp, p);

T m2 = Xpow(c, dq, q);
trigger_low();

We discovered experimentally that parameters offset = -3 and width = 6 give good results. We repeat computations 10 times, every time glitching in a different clock cycle and print results:

We can see that in a few cases we get the valid signature, which means that the glitch didn’t interfere with computations, but we also get a couple of faulty signatures: (0xffffffffffffffa9) = -87 and (0x0141) = 321. When we compute gcd(S-S’,N) we get one of the factors of N.

This is a very simple and repeatable attack we can perform using glitch, also possible to conduct having only message m and a faulty signature instead of a valid signature and a faulty one.

Source code and Jupyter notebooks for this post can be found here.

Leave a Reply

Close Menu