As of August 2020 the site you are on (wiki.newae.com) is deprecated, and content is now at rtfm.newae.com.

Tutorial A3 VCC Glitch Attacks

From ChipWhisperer Wiki
Revision as of 09:39, 12 April 2018 by Fheubach (Talk | contribs) (Addition of aux settings tab)

Jump to: navigation, search

For the older V3.x tools, see V3:Tutorial A3 VCC Glitch Attacks

This advanced tutorial will demonstrate power glitch attacks using the ChipWhisperer system.

Background on VCC (Power) Glitching

The previous clock glitching tutorials looked into the assumption of a constant clock. But instead we can modify the voltage of the device, causing for example a failure to correctly read a memory location or otherwise cause havoc with the proper functioning.

caption Top trace is the VCC (power) measured at the microcontroller pin, lower trace is the clock to the device.
caption A zoom in of the previous figure, showing the offset between the clock and the glitches.
caption Changing the offset means the glitches are ineffective - this requries considerable experimentation to discover the value for offset, glitch width, and number of glitches.

Background on Glitch Generation

For more details, please see Tutorial_A2_Introduction_to_Glitch_Attacks_(including_Glitch_Explorer), this tutorials assumes you have already performed the clock glitching tutorial. This tutorial will use the Glitch Explorer, which is described in the previous tutorial.

The glitch generation hardware is the same as used in the clock glitching attack. The generated glitches are synchronous to the device clock, and inserted at a precise offset from the clock edge.

Glitches can be inserted continuously or triggered by some event. The following figure shows the generation of two glitches:

Glitchgen-mux-glitchonly.png

The VCC glitching method here uses an electronic switch (a MOSFET) to short the power line to GND at specific instances. The following figure shows the basic function of this system:

Glitch-vccglitcher.png

This method allows use with the standard side-channel analysis development board, which has resistors inserted into the VCC lines already. The downside of this method is that it can only generate short glitches, since the power consumption through the shunt resistor will short out the resistor.

The MOSFET glitching hardware is built into the ChipWhisperer-Lite (both CW1173 and CW1180) board. The ChipWhisperer-Capture Rev2 uses an external VCC glitching board.

Hardware Setup

ChipWhisperer-Lite (CW1173) with built-in XMEGA Target

The XMEGA target will work out-of-the-box for this tutorial. As usual, no hardware setup is required - everything on the CW-Lite board is ready to go.

ChipWhisperer-Lite (CW1173/CW1180) with external AVR (NOTDUino/Multi-Target)

The AVR is an extremely reliable target to glitch. To do this, you need to connect the following cables:

  1. SMA Cable from the Glitch port to the VCC shunt.
  2. 20-Pin Target Cable for Clock & Data.
  3. Optional: SMA Cable from the Measure port to the VCC shunt (can be used to monitor glitch insertion).

The following shows an example of connecting the NOTDuino target to the ChipWhisperer-Lite:

image

If using a target with only a single SMA, only connect the Glitch port. The measure port is optional to allow you to monitor the VCC line as you are inserting the glitch.

Setting up Glitch Example

Firmware Setup

Just as in the clock glitching example, you will be required to program the AVR microcontroller with an example you can glitch. Once again program in the glitch example code to use the glitch1() function, as described in Tutorial_A2_Introduction_to_Glitch_Attacks_(including_Glitch_Explorer).

If using the AVR target, be sure to modify the makefile to select the new target type (i.e. if you previously targeted the XMEGA, that hex-file will not work on the NOTDuino).

Programming the device is also described in Step #4 in the following section.

Software Setup

  1. Select the connect_simpleserial.py script

    Connect script.png

  2. Run the connect_simpleserial.py script, by pressing the Run button

    Connect script preview.png

  3. Setup up the settings by running the appropriate setup script for your device

    Setup script xmega.png

  4. Run the setup script by pressing the run button, if you want to see what parameters the script changes, inspect the preview

    Setup preview xmega.png

  5. Open the appropriate programmer from top main menu Tools, and in the dialog press Check Signature to verify you can connect to the target

    Xmega programmer.png

  6. Find the correct firmware file, previously compiled for the target you are using, and press the Erase/Program/Verify FLASH

    Xmega programmer press program.png

  7. Time to setup the voltage glitching parameters. Start with the Glitch Module section under the Scope Settings tab

    1. Set the Clock Source as CLKGEN:

    2. Setup the Glitch Module to NOT output anything by default VERY IMPORTANT TO AVOID DAMAGE

      Set the Output Mode as Glitch Only, this is the step that insures you do not cause constant glitches:

    3. Set the Glitch Trigger to Ext Trigger:Single-Shot

    Glitch setup.png

  8. Now activate the lower power glitch module, by enabling the HS-Glitch Out Enable (Low Power) toggle under Trigger Pins section in the Scope Settings tab

    For the ChipWhisperer-Lite (CW1173/CW1180), set Target HS IO-Out option to CLKGEN.

    Low power glitch enable.png

  9. Navigate to the Target Settings tab and remove all the text in the Load Key Command, Go Command, and Output Format fields

    Set the Output Format field to r$GLITCH$\n

    Target output setting.png

  10. Run the aux reset script for the appropriate target. The avr, stm32f and xmega targets use the aux_reset_cw1173.py. This scripts needs to be modified for the specific target. Uncomment the line for your target and comment out the lines for the other targets. The timing of the reset can also be changed, the comments explain the pros and cons of each. The reset after arm usually works better and needs less setup, but this depends on the target.

    """Set up resets via CW1173
    Contains a few adjustable lines to switch between XMEGA/AVR/STM32F and change reset
    timing (relative to scope arm)
    """
    
    from chipwhisperer.capture.auxiliary.ResetCW1173Read import ResetCW1173
    
    # GUI compatibility
    try:
        aux_list = self.aux_list
    except NameError:
        pass
    
    # Delay between arming and resetting, in ms
    delay_ms = 1000
    
    # Reset XMEGA device
    Resetter = ResetCW1173(pin='pdic', delay_ms=delay_ms)
    # Reset STM32Fx device
    #Resetter = ResetCW1173(pin='nrst', delay_ms=delay_ms)
    # Reset AVR
    #Resetter = ResetCW1173(pin='nrst', delay_ms=delay_ms)
    
    # Reset before arming
    # avoids possibility of false triggers
    # need delay in target firmware to avoid race condition
    #aux_list.register(Resetter.resetThenDelay, "before_trace")
    
    # Reset after arming
    # scope can catch entire reset
    # avoids race condition
    # target reset can cause false triggers (usually not an issue)
    aux_list.register(Resetter.delayThenReset, "after_arm")
    
  11. You can see what aux modules are active in the Aux Settings tab. Here you can see the preview, enable/disable, and remove each module

    Aux setting.png

Monitoring Glitch Insertion

We can optionally enable the power analysis capture, and monitor how the power consumption changes as we insert a glitch. To do this:

  1. Switch to the Scope Settings tab.
  2. Switch the ADC Clock Source as being CLKGEN x4.
  3. Press Reset ADC DCM, confirm the frequency is 29.5 MHz as expected.
  4. Switch the Trigger Setup --> Mode to be Rising Edge
  5. Switch the Trigger Setup --> Total Samples to be 1000
  6. Switch the Gain Setting --> Setting to be 40. You might need to adjust this for different hardware.
  7. Press Capture 1, confirm some waveform is displayed. For example with the NOTDuino Target on the ChipWhisperer-Lite, the waveform looks like this:

    image

  8. If this does't work: check the trigger in use is the Target IO4 pin.
  9. Play around a bit with the glitch width, offset, and repeat. You should see different effects in the power consumption traces. For example the following shows a narrow (15% pulse width) glitch being inserted:

    image

Starting the Glitch Attack

We'll now look at glitching this routine. As before after sending the A the system goes into an infinite loop, and sends 1234 after exiting from the loop. Using VCC glitching we'll escape from this loop!

Rather than using the manual trigger, we'll jump right into using the Glitch Explorer to break this target. First, we'll setup some basic glitch parameters for your specific target.

  1. Switch to the Target Settings tab, and set the Output Format to $GLITCH$.
  2. Open the Glitch Explorer, and hit Capture 1 a few times. Confirm this populates the table with various examples.

    image

  3. We need to setup the Normal Response and Successful Response. Note in this example the normal response has a little random noise we want to ignore, but we want to capture when the device resets after the glitch and sends the "hello" message twice. We could accomplish this with the following bit of Python code:

    s.endswith("hello\nA") and (len(s) < 12)

    This looks for both the ending without glitch, and the length of the string isn't too long. In the case of the successful glitch, we just want to see if "1234" is printed. This can be accomplished in Python with:

    "1234" in s

    You can always experiment using the Python Console to see how your potential systems work. For example here is checking that the first line works:

    >>> s = "\x1ahello\nA"
    >>> s.endswith("hello\nA") and (len(s) < 12)
    True
    >>> s = "\x1ahello\nAhello\nA"
    >>> s.endswith("hello\nA") and (len(s) < 12)
    False

    Finally, configure the Glitch Explorer:

    1. Set the Normal Response to s.endswith("hello\nA") and (len(s) < 12)
    2. Set the Successful Response to "1234" in s

    You can test the updated color-coding seems to be working too with a few Capture 1 events.

  4. Using the following table, set the Glitch Width (as % of period) and Repeat on the Scope Settings tab:

    Parameter AVR on Multi-Target or NOTDuino
    Glitch Width (as % of period) 49
    Repeat 10
  5. Finally, let's configure the Glitch Explorer to sweep the Offset and Width parameters by running the ge_widthoffset_vary.py. The starting, stopping and step attributes can be changed for both parameters by editing the script

    """Glitch Explorer example to modify clock offset & width.
    
    To use this be sure to set 'Output Format' as $GLITCH$ so data is passed through.
    """
    
    class IterateGlitchWidthOffset(object):
        def __init__(self, ge_window):
            self._starting_offset = -40
            self._starting_width = -40
            self.ge_window = ge_window
    
        def reset_glitch_to_default(self, scope, target, project):
            """ Set glitch settings to defaults. """
            self.offset = self._starting_offset
            self.width = self._starting_width
    
        def change_glitch_parameters(self, scope, target, project):
            """ Example of simple glitch parameter modification function. """
            # This value is minimum clock offset/width increment
            scope.glitch.offset += 0.390624
    
            if scope.glitch.offset > 40:
                scope.glitch.offset = self._starting_offset
                scope.glitch.width += 0.390624
    
            if scope.glitch.width > 40:
                scope.glitch.width = self._starting_width
    
            # Write data to scope
            #scope.glitch.width = self.width
            #scope.glitch.offset = self.offset
    
            #You MUST tell the glitch explorer about the updated settings
            if self.ge_window:
                self.ge_window.add_data("Glitch Width", scope.glitch.width)
                self.ge_window.add_data("Glitch Offset",scope.glitch.offset)
    
    glitch_iterator = IterateGlitchWidthOffset(self.glitch_explorer)
    self.aux_list.register(glitch_iterator.change_glitch_parameters, "before_trace")
    #self.aux_list.register(glitch_iterator.reset_glitch_to_default, "before_capture")
    
  6. On the General Settings tab:

    1. Ensure the Trace Format is set to None (i.e., no traces will be written to disk).
    2. Set the Number of Traces to 200.
  7. Press the Capture Multi button. You will get a warning as there is no trace writer, but can just hit Continue Anyway, since we do not want to store traces to disk.
  8. Hopefully you will determine some useful parameters for glitching this target:

    image

  9. Try reducing the Repeat parameter in the Glitch Module settings. See how few cycles you can glitch while still achieving a reliable glitch.

Once you have the glitch parameter determined, you can work on trying to recreate some of the previous tutorials such as glitching passed the password prompt.

Glitching More Advanced Targets: Raspberry Pi

It is also possible to glitch more advanced targets, such as the Raspberry Pi development board! This requires some additional hardware setup which will be discussed here.

The Raspberry Pi is a small ARM-based computer that runs Linux. This tutorial will show you how to influence a program running in userland via voltage glitching.

We will use the ChipWhisperer-Lite board, as it has integrated high-power glitching MOSFET.

Hardware Setup

warning

This tutorial can cause permanent damage to your Raspberry Pi board. The generation of glitches means driving the power supply and device beyond limits specified in the absolute maximum ratings. Only perform this tutorial if you are not too attached to your Raspberry Pi board.

YOU PERFORM THIS TUTORIAL AT YOUR OWN RISK. NEWAE TECHNOLOGY INC. IS NOT RESPONSIBLE FOR DAMAGE CAUSED BY FOLLOWING THIS TUTORIAL.

To glitch the board, you must solder a wire onto the VDD_CORE power supply, ideally as close to the BGA power pin as possible. To do this identify the power plane by looking at the schematic:

image

And then solder a wire onto the VCC side of a decoupling capacitor, such as C65. Check the polarity with a DMM to ensure you have the positive side and solder a fine wire to it.

image

image

We will now mount a connector so we can connect this to the ChipWhisperer-Lite Glitch port. This will require you to check your specific revision - on this board an empty hole (test point) labeled "TP2" connects to ground, and made a handy location to connect the SMA connector to ground.

The following shows an example of soldering the SMA connector onto the board, note the GND is soldered on both top and bottom to give additional strength:

image

The positive side of the capacitor connects to the inner conductor of the SMA "GLITCH" port, and connect the outer connector to ground on the Raspberry Pi. At this point do not yet plug into the GLITCH port, we will do that once setup is complete.

Finally you need to boot the Raspberry Pi and connect to it. This is suggested to be done with a SSH shell over the Ethernet connection, as the Ethernet connection typically has very good protection against voltage transients. If you connect the Raspberry Pi to a monitor over HDMI, there is a chance the glitches may cause invalid voltage levels on the HDMI port which could damage your monitor.

Once you have connected to it, simply make a file called glitch.c with the following contents:

#include <stdio.h>

int main(void){
    int i,j,k,cnt;
    k = 0;
    while(1){
     cnt = 0;
     for(i=0; i<5000; i++){
       for(j=0; j<5000; j++){
          cnt++;
       }
     }
     printf("%d %d %d %d\n", cnt, i, j,k++);
    }
}

Compile to an executable with:

$ gcc glitch.c -o glitch

And run the executable:

$ ./glitch
25000000 5000 5000 0
25000000 5000 5000 1
25000000 5000 5000 2
25000000 5000 5000 3
25000000 5000 5000 4
25000000 5000 5000 5

The output is split into two parts. The first three are used to monitor the glitch insertion (this is the 25000000 5000 5000, the second makes it easier for you to confirm if the Raspberry Pi has crashed.

Now that you have a working system - let's break it!

Glitch Parameters

Glitching the Raspberry Pi is very simple. We just need to generate an appropriately sized glitch, as the following shows:

  1. Start ChipWhisperer-Capture.
  2. Set the Scope Module to ChipWhisperer/OpenADC, and the connection to ChipWhisperer-Lite.
  3. Hit the Scope Connect button. There is no target for this example.
  4. Set the CLKGEN frequency to 120 MHz.
  5. Set the Glitch module Source to CLKGEN.
  6. Set the Glitch Mode to Enable Only.
  7. Ensure the Glitch Trigger is Manual.
  8. Set the Repeat to 38.
  9. Click the HS-Glitch Out Enable (High Power) check-box.
  10. Connect the SMA cable for the glitch output to the Raspberry Pi.
  11. With the output of the glitch program running, hit the Manual Trigger button. This will cause a glitch to be inserted, and observe the output of your glitch program.

    Most likely the glitch width was insufficient for a glitch to be inserted, so increase the Repeat count to increase the width, and try pressing the Manual Trigger button again. In this example a glitch was successfully inserted with a width of 52, so you might want to try a few larger numbers. If you do things wrong your Raspberry Pi will crash and you'll need to reboot it and continue experimenting.

    The following shows an example of inserting several glitches successfully:

    image