Introduction

Power analysis is a side channel attack where the changes in the power consumption of the device are used to extract some secret, usually the encryption keys.

On September 19th on this year’s BalCCon 2k26 I gave a talk titled Power Analysis Attacks 101: From Waveform to Private Key (info here). The video of the talk should be up soon. Slides are available at https://hglt.ch/dpa_balccon.pdf.

In the talk I presented the history and theory behind the differential/correlation power attacks. It’s a known method, dating back to 1998, which is still being used (in more advanced forms). Since it’s a known thing there are many setups which can be used for demonstration, and the simplest/most popular way is by using the Chip Whisperer. However, I wanted to use some setup which hasn’t been used before.

Checking through my pile of gadgets I first wanted to use RedPitaya but that’s also been done before. So I decided to go with Glasgow digital interface explorer. Glasgow is an FPGA based digital multitool which can be used to handle different digital protocols. But it’s only digital so I needed to build an analog frontend for it.

Pretty good explanation of the whole differential/correlation power analysis can be found in many places, such as The Hardware Hacking Handbook book by Jasper van Woudenberg and Colin O’Flynn, which is an amazing book (check it) or for example in this article so I’m not going to try to explain it here. Here’s also an amazing writeup by Kévin Courdesses where he explains a real-world scenario of breaking the flash encryption on Espressif chips.

Hardware

Basically, the idea was to build a ChipWhisperer style power trace acquisition. I wanted to go with synchronous sampling where the instrument provides the clock for the device and handles the sampling of the power consumption in sync with that clock (the async approach would require faster sampling and a higher number of collected samples). The power consumption is measured the usual way, by inserting a shunt resistor inline with the device power supply, amplifying the voltage drop on it and measuring the value. Since the power fluctuations are miniscule (sub-microamps) a special care should be taken to properly extract a signal (it later turned out that the simple case can be handled even with a lousy signal).

GIE-SPARK board schematic

I named the addon board GIE-SPARK: Glasgow Interface Explorer Synchronous Power Acquisition & Reconnaissance Kit. It contains an onboard 20Ω shunt resistor, possibility to attach to the external resistor, fully differential amplifier (THS4541) with the gain of 50, 8-bit ADC (AD9280), variable power supply, clock output, UART lines and some control lines (trigger, reset, gpio). I missed the opportunity to also add a MOSFET based crowbar circuit which could be used for voltage glitching attack but I might add that in the next revision. I also assigned the pins before thinking about gateware so in the end I couldn’t use the PLL on the FPGA leaving only the clock/sampling frequencies which can be derived directly from 48MHZ clock (8MHz, 12MHz, 16MHz, 24MHz, 48MHz) which turned out not to be a limitation (I ran all of my tests with clock at 8MHz and sampling at 24MHz).

Rendered image of the PCB

Some changes were required after the initial build in order to get better results: increased shunt value (was 10Ω), increased amplifier gain (was 10x) and added antialiasing filter (3MHz cutoff).

Two images below show the example power trace before and after the modification (note the range of values on y-axis). Both are showing the same event from the demo board (AES initialization and first 1.5 rounds). Fun thing is that even with the first signal and 2000 recorded traces I was able to correctly extract 11 out of 16 bytes of the key so with more traces the full key could be extracted. With the improved setup I got 16/16 with 500 traces every time (at least 20-30 test runs) except once which happened on BalCCon stage when I was demoing the setup.

Power trace recorded with original board
Same power trace after modifications

Hardware design files for the board are available at https://gitlab.com/hyperglitch/gie-spark .

Demonstration setup

I also didn’t want to use some existing prepared target, such as the boards available for ChipWhisperer but some standard board – I went with the STM32 NUCLEO-F303RE. But I wanted to use the same microcontroller as one of the ChipWhisperer targets so I can use the same demo firmware.

A demonstration setup I used for the BalCCon2k26 talk

On the Nucleo board I removed the jumpers which tied the MCU clock input to the STLink debugger clock and connected my clock output there. I also removed three decoupling capacitors next to the MCU: one 1uF and two 100nF capacitors. The GIE-SPARK onboard shunt was used.

Demo setup wiring

The demo firmware runs the tinyAES implementation of AES. I also tested it with mbedTLS implementation which is slightly different. Both are software implementations where the mbedTLS is more efficient as it handles two AES rounds at time. This setup can be used also to attack the hardware implementation but it gets more complicated (different leakage model required, more samples needed) and not suitable for the talk demo.

It’s important to note that power analysis attacks don’t attack the encryption algorithm – they attack the weaknesses in the implementation of the algorithm.

Software/gateware

During the work on JellyfishOPP I wrote some Verilog and I understand the concepts but some time has passed since the last time I wrote FPGA code and it would take me a lot more time than I had to get familiar with Amaranth and write the gateware for GIE-SPARK board. Claude code to the rescue!

❯ glasgow run spark -V 3.3 --uart-tx B3 --uart-rx B4 --baud 38400 -K 2 -p 1 -d 12288  acquire -n 500 --verify -o test_run
W: g.support.plugin: loading out-of-tree plugin 'glasgow-spark'; plugin API is currently unstable and subject to change without warning
I: g.hardware.device: generating bitstream ID d92d5892a49221b7
I: g.hardware.assembly: port * voltage set to 3.3 V
W: g.hardware.device: fault: port A: supply overcurrent
I: g.cli: running handler for applet 'spark'
W: glasgow_spark.capture: port A is not at 3.30 V; re-applying with a 250 mA trip current (attempt 1 of 4)
I: g.hardware.assembly: port * voltage set to 3.3 V
I: glasgow_spark.capture: supplies came up on attempt 2
I: glasgow_spark.capture: collecting 500 traces of 12288 samples at 24.000 MHz (512.0 us) into test_run-*
I: glasgow_spark.capture: 50/500 traces (14.3/s)
I: glasgow_spark.capture: 100/500 traces (14.3/s)
I: glasgow_spark.capture: 150/500 traces (14.4/s)
I: glasgow_spark.capture: 200/500 traces (14.3/s)
I: glasgow_spark.capture: 250/500 traces (14.3/s)
I: glasgow_spark.capture: 300/500 traces (14.3/s)
I: glasgow_spark.capture: 350/500 traces (14.3/s)
I: glasgow_spark.capture: 400/500 traces (14.3/s)
I: glasgow_spark.capture: 450/500 traces (14.3/s)
I: glasgow_spark.capture: 500/500 traces (14.3/s)
I: glasgow_spark.capture: wrote test_run-traces.bin (6144000 bytes), -plaintexts.bin, -ciphertexts.bin and -meta.json

Together with Claude I made the Glasgow applet for the board, the python script for correlation power analysis attack (tools/cpa.py) and a script for plotting the power traces (tools/traceview.py)

❯ python tools/cpa.py run18 --traces 500
500 traces x 12288 samples

byte  guess       r   2nd  margin  sample  correct key
   0     2b   0.331    b6   0.121     994  ok
   1     7e   0.298    9a   0.057    1573  ok
   2     15   0.225    88   0.008    2445  ok
   3     16   0.285    96   0.067    1433  ok
   4     28   0.320    c2   0.109    1066  ok
   5     ae   0.314    60   0.098    1550  ok
   6     d2   0.320    b5   0.103    1287  ok
   7     a6   0.341    16   0.123    1466  ok
   8     ab   0.259    d6   0.035    1093  ok
   9     f7   0.326    57   0.087    1557  ok
  10     15   0.342    dc   0.133    1574  ok
  11     88   0.275    bd   0.063    1448  ok
  12     09   0.236    95   0.003    1086  ok
  13     cf   0.397    28   0.185    1561  ok
  14     4f   0.381    be   0.150    1586  ok
  15     3c   0.291    d8   0.018    1638  ok

correct key ranked 1st on 16 bytes, in the top 3 on 16, top 10 on 16 of 16
median rank 1 out of 256 guesses

recovered 2b7e151628aed2a6abf7158809cf4f3c
actual    2b7e151628aed2a6abf7158809cf4f3c
16/16 bytes correct

All of the code is available at https://gitlab.com/hyperglitch/gie-spark-applet. The repository also contains README explaining how to run it.

Comments

Go to top