
Table of Contents
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).
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).

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.


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.

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.

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.
