Guide ‐ First Power Analysis Attack - miswired/glitchy GitHub Wiki

This page walks you through a demonstration for power analysis to gain insight into the internal execution cycle of the Arduino Uno.

Making Connections

We need to make some new connections that are different from the glitching setup. You can disconnect all the wires between the two boards if you still have that setup wired up.

In order to monitor the power we will be providing power to the Arduino this time.

  • If you already did the glitching example, we can connect the positive power line that we soldered on to the "Out Target" terminal of the power monitoring screw terminal. If you didn't, you can use a male jumper wire and plug it into the 5V terminal next to the power cap and into the screw terminal instead. The soldered line will be more reliable however.
  • Take a jumper wire and run it from the 3.3V pin on the Glitchy to the "In Supply" terminal. We are going to power the Arduino Uno with 3.3v instead of it's usual 5V because it can run on 3.3V and our amp input would need us to connect the optional external power supply to raise the vcc line of the amp high enough to detect higher voltages. All of that detail and instructions will be in the circuit theory section. For now don't worry about it for this example.

IMPORTANT If you leave the USB plug in the Arduino Uno while trying to do this example, the Uno will take power from there and not our board and you will get no results.

  • And of course we need to connect the GND lines of both boards up like before. The easiest way to do this is with a jumper wire between both terminals marked GND like below.

20240806_224003

Now we need to connect up the "key" pins. There are three pins that we are using as input to keys and we want to see if we can detect a change in program execution between them. This is handy because often times coded for a correct key stroke is different from the other keys pressed on something like electronic lock.

Glitchy Pin / Arduino Pin
5/5
6/6
7/7

Loading up the target software

If you have not yet setup the Arduino IDE and pulled the repo. Please go back to the glitching example and follow the instructions there to get set up. We will be loading the Target Examples > Target_keypad program to the Arduino Uno.

// Defining Pins here
#define ENTER_KEY_PIN       2   
#define KEY_1_PIN           5
#define KEY_2_PIN           6
#define KEY_3_PIN           7

#define LOCKED_LED_PIN      12 
#define UNLOCKED_LED_PIN    11
#define STATUS_LED_PIN      13     

//Globals
bool g_button_state = false;         // variable for reading the pushbutton status
volatile bool g_unlocked = false;   //volatile so that the optimizer doesn't remove the code since it is always false
bool g_was_the_right_key_pressed = false;

void setup() {
  // initialize pin registers
  pinMode(LOCKED_LED_PIN, OUTPUT);
  pinMode(UNLOCKED_LED_PIN, OUTPUT);
  pinMode(ENTER_KEY_PIN, INPUT_PULLUP);
  pinMode(STATUS_LED_PIN, OUTPUT);
  digitalWrite(STATUS_LED_PIN, LOW);

  //Note, this example expects the pins to be pulled high and low, no pullup needed.
  pinMode(KEY_1_PIN, INPUT_PULLUP);
  pinMode(KEY_2_PIN, INPUT_PULLUP);
  pinMode(KEY_3_PIN, INPUT_PULLUP);


  // Show locked
  digitalWrite(LOCKED_LED_PIN, HIGH);
  digitalWrite(UNLOCKED_LED_PIN, LOW);

  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);

  Serial.println("Booted, waiting for key press\n");
}

void loop() {
  if(!digitalRead(KEY_1_PIN))
  {
    g_was_the_right_key_pressed = false;
    Serial.println("Key 1 Pressed\n");
  }

    if(!digitalRead(KEY_2_PIN))
  {
    g_was_the_right_key_pressed = false;
    Serial.println("Key 2 Pressed\n");
  }

  //In this example, we only care if key 3 is pressed, because it's the right key.
  if(!digitalRead(KEY_3_PIN))
  {
    g_was_the_right_key_pressed = true;
    //Do some extra operation to simulate a different execution path
    float prime = ({int p=2,n=0,f;for(;n</**/100/**/;p++)for(f=2;(f<p||!++n)&&p%f++;);--p;});
    Serial.println(prime);
    delayMicroseconds(100);
    Serial.println("Key 3 Pressed\n");
  }


  

  //Check to see if button is pressed and we should evaluate the password
  if (!digitalRead(ENTER_KEY_PIN)) {
    Serial.println("Enter Key Pressed\n");
    if(g_was_the_right_key_pressed)
    {
      unlock_system();
    }
  } 
}


void unlock_system()
{
  digitalWrite(LOCKED_LED_PIN, LOW);
  digitalWrite(UNLOCKED_LED_PIN, HIGH);
}

The Key part of the code here is the calculation of the prime number on key 3.

    //Do some extra operation to simulate a different execution path
    float prime = ({int p=2,n=0,f;for(;n</**/100/**/;p++)for(f=2;(f<p||!++n)&&p%f++;);--p;});

Our goal is to see a difference in power for that key.

Adjust the analog front end

As in the glitch example, connect to the board, but go do the Power Analysis Setup screen. And turn on the streaming.

Screenshot_20240929_113242

These two voltages are the bias point mid amp and the amp output. The analog front end will be explained in depth the circuit theory section of the wiki, here we will gloss over the more in depth details.

The first thing we need to do is set the sensor resistor. The goal is to get the highest resistance that will not prevent the Arduino from functioning correctly. The higher the resistance, the bigger the signal we can detect.

20240806_224639

Reading the front of the board, you can see in the example that I have 7 ohms set up here. But you can try different resistances. UPDATE: It appears to work well with all resistors enabled (with the 8th user installed location shorted of course since we don't have anything there.)

IMPORTANT
The #8 switch needs to be set to shorted (ON position). This switch is there to let you install a resistor of any resistance that you like into the R21 position and use that. Since there is nothing installed there currently, leaving it open and not shorted out will mean you do not complete the circuit and you will not power the Arduino. So if you are getting no power to the Arduino, check that.

Now we need to adjust our analog front end. The goal is to get as much amplification as possible without maxing out the system so we can detect the very tiny changes in current that the Arduino will use while it runs. Again, we are going to gloss over the details and go in depth in the circuit theory part of the wiki later.

Your goal will be to set the bias point to about 0.5V and the gain to about 2.5V.

Running the analysis

Now we need to go to the Power Analysis by clicking the Go To Analysis button. There click on the Start Analysis button. The program will press each key on the Arduino, capturing the power traces. You may have to run the test a couple times to compare and see a clear difference. Sometimes noise and timing shifts the traces slightly and we are trying to measure very small differences here. Your graph should look like the following.

Screenshot_20240929_113613

Here we see that Key three is clearly on a different execution path. Try modifying the Arduino code and see what affects it. Maybe change swap some wires so key 3 is now key 2 and see if your traces follow your results.

Tips

  • Try using the cursor to read individual data points or drag over an area to zoom into the graph.
  • Run multiple tests, the board is trying to read very small changes in current and sometimes electrical noise is just poorly timed.
  • If you are not seeing a strong difference, try lowering the bias voltage and raising the gain more. This will make the readings more sensitive.