Measuring SNR of Target

Supported setups:

SCOPES:

  • OPENADC

  • CWNANO

PLATFORMS:

  • CWLITEARM

  • CWLITEXMEGA

  • CWNANO

In [1]:

SCOPETYPE = 'OPENADC'
PLATFORM = 'CWLITEXMEGA'
CRYPTO_TARGET = 'TINYAES128C'

In [2]:

%%bash -s "$PLATFORM" "$CRYPTO_TARGET"
cd ../hardware/victims/firmware/simpleserial-aes
make PLATFORM=$1 CRYPTO_TARGET=$2

Out [2]:

rm -f -- simpleserial-aes-CWLITEXMEGA.hex

rm -f -- simpleserial-aes-CWLITEXMEGA.eep

rm -f -- simpleserial-aes-CWLITEXMEGA.cof

rm -f -- simpleserial-aes-CWLITEXMEGA.elf

rm -f -- simpleserial-aes-CWLITEXMEGA.map

rm -f -- simpleserial-aes-CWLITEXMEGA.sym

rm -f -- simpleserial-aes-CWLITEXMEGA.lss

rm -f -- objdir/*.o

rm -f -- objdir/*.lst

rm -f -- simpleserial-aes.s simpleserial.s XMEGA_AES_driver.s uart.s usart_driver.s xmega_hal.s aes.s aes-independant.s

rm -f -- simpleserial-aes.d simpleserial.d XMEGA_AES_driver.d uart.d usart_driver.d xmega_hal.d aes.d aes-independant.d

rm -f -- simpleserial-aes.i simpleserial.i XMEGA_AES_driver.i uart.i usart_driver.i xmega_hal.i aes.i aes-independant.i

.

-------- begin --------

avr-gcc (WinAVR 20100110) 4.3.3

Copyright (C) 2008 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



.

Compiling C: simpleserial-aes.c

avr-gcc -c -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/simpleserial-aes.lst -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/simpleserial-aes.o.d simpleserial-aes.c -o objdir/simpleserial-aes.o

.

Compiling C: .././simpleserial/simpleserial.c

avr-gcc -c -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/simpleserial.lst -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/simpleserial.o.d .././simpleserial/simpleserial.c -o objdir/simpleserial.o

.

Compiling C: .././hal/xmega/XMEGA_AES_driver.c

avr-gcc -c -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/XMEGA_AES_driver.lst -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/XMEGA_AES_driver.o.d .././hal/xmega/XMEGA_AES_driver.c -o objdir/XMEGA_AES_driver.o

.

Compiling C: .././hal/xmega/uart.c

avr-gcc -c -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/uart.lst -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/uart.o.d .././hal/xmega/uart.c -o objdir/uart.o

.

Compiling C: .././hal/xmega/usart_driver.c

avr-gcc -c -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/usart_driver.lst -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/usart_driver.o.d .././hal/xmega/usart_driver.c -o objdir/usart_driver.o

.

Compiling C: .././hal/xmega/xmega_hal.c

avr-gcc -c -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/xmega_hal.lst -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/xmega_hal.o.d .././hal/xmega/xmega_hal.c -o objdir/xmega_hal.o

.

Compiling C: .././crypto/tiny-AES128-C/aes.c

avr-gcc -c -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/aes.lst -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/aes.o.d .././crypto/tiny-AES128-C/aes.c -o objdir/aes.o

.

Compiling C: .././crypto/aes-independant.c

avr-gcc -c -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/aes-independant.lst -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/aes-independant.o.d .././crypto/aes-independant.c -o objdir/aes-independant.o

.

Linking: simpleserial-aes-CWLITEXMEGA.elf

avr-gcc -mmcu=atxmega128d3 -I. -DNO_EXTRA_OPTS -fpack-struct -gdwarf-2 -DSS_VER=SS_VER_1_1 -DHAL_TYPE=HAL_xmega -DPLATFORM=CWLITEXMEGA -DTINYAES128C -DF_CPU=7372800UL -Os -funsigned-char -funsigned-bitfields -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=objdir/simpleserial-aes.o -I.././simpleserial/ -I.././hal -I.././hal/xmega -I.././crypto/ -I.././crypto/tiny-AES128-C -std=gnu99 -MMD -MP -MF .dep/simpleserial-aes-CWLITEXMEGA.elf.d objdir/simpleserial-aes.o objdir/simpleserial.o objdir/XMEGA_AES_driver.o objdir/uart.o objdir/usart_driver.o objdir/xmega_hal.o objdir/aes.o objdir/aes-independant.o --output simpleserial-aes-CWLITEXMEGA.elf -Wl,-Map=simpleserial-aes-CWLITEXMEGA.map,--cref   -lm

.

Creating load file for Flash: simpleserial-aes-CWLITEXMEGA.hex

avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature simpleserial-aes-CWLITEXMEGA.elf simpleserial-aes-CWLITEXMEGA.hex

.

Creating load file for EEPROM: simpleserial-aes-CWLITEXMEGA.eep

avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" 
    --change-section-lma .eeprom=0 --no-change-warnings -O ihex simpleserial-aes-CWLITEXMEGA.elf simpleserial-aes-CWLITEXMEGA.eep || exit 0

.

Creating Extended Listing: simpleserial-aes-CWLITEXMEGA.lss

avr-objdump -h -S -z simpleserial-aes-CWLITEXMEGA.elf > simpleserial-aes-CWLITEXMEGA.lss

.

Creating Symbol Table: simpleserial-aes-CWLITEXMEGA.sym

avr-nm -n simpleserial-aes-CWLITEXMEGA.elf > simpleserial-aes-CWLITEXMEGA.sym

Size after:

   text        data     bss     dec     hex filename

   4064         556     248    4868    1304 simpleserial-aes-CWLITEXMEGA.elf

+--------------------------------------------------------

+ Built for platform CW-Lite XMEGA

+--------------------------------------------------------

Signal to Noise Ratio (SNR)

In general, the “Signal to Noise Ratio” is defined as:

\[SNR = \frac{Var(Signal)}{Var(Noise)}\]

This is to say the variance in the signal measured compared to the variance in the noise measured. You will often see SNR expressed in dB, which is a logarithmic scale. In which case the conversion is simply done as:

\[SNR_{dB} = 20log(SNR)\]

Note this assumes our measurements were voltages – the 20 infront of the log is done to represent the fact that SNR is typically referencing the power difference between signal and noise. The power across a resistor would be equal to the square of the voltage, so we should actually have:

\[SNR_{dB} = 10log\left( \left( \frac{Var(Signal)}{Var(Noise)}\right)^2\right) = 20log\left( \frac{Var(Signal)}{Var(Noise)}\right)\]

What’s the Signal?

The above was very easy to right out. But what is the signal, and what is the noise? The signal is going to be the leakage we measured based on some leakage function, and the noise will be the noise inherent in the measurement not caused by the leakage.

The easiest way to do this will be to find the average trace for each leakage “group”. If using the Hamming weight leakage model, this means we have 9 traces (one for each HW). If we used classic DPA we would have two groups (one for each bit).

Within each group, we can measure the noise. We don’t actually measure across all groups since then we would have the leakage contributing to our “noise”. We want to get a measure of only the noise, not variance being caused by the signal.

Outline of this Tutorial

As usual, we’re going to first go through a detailed example. We’ll then give you some quick cheater functions to calculate the SNR based on leakage models built into ChipWhisperer (yay!). This makes it easy to quickly compare leakage models.

Capturing Power Traces

The capture part is the same as previous tutorials. We include it here to make it interactive.

Setup

We’ll use some helper scripts to make setup and programming easier. If you’re using an XMEGA or STM (CWLITEARM) target, binaries with the correct should be setup for you:

In [3]:

%run "Helper_Scripts/Setup_Generic.ipynb"

In [4]:

fw_path = "../hardware/victims/firmware/simpleserial-aes/simpleserial-aes-{}.hex".format(PLATFORM)

In [5]:

cw.program_target(scope, prog, fw_path)

Out [5]:

XMEGA Programming flash...
XMEGA Reading flash...
Verified flash OK, 4619 bytes

Capturing Traces

Below you can see the capture loop. The main body of the loop loads some new plaintext, arms the scope, sends the key and plaintext, then finally records and appends our new trace to the traces[] list. At the end, we convert the trace data to numpy arrays, since that’s what we’ll be using for analysis.

In [6]:

#Capture Traces
from tqdm import tnrange
import numpy as np
import time


ktp = cw.ktp.Basic()

traces = []
N = 1000  # Number of traces
if PLATFORM == "CWNANO":
    N = 1500

for i in tnrange(N, desc='Capturing traces'):
    key, text = ktp.next()

    trace = cw.capture_trace(scope, target, text, key)
    if trace is None:
        continue
    traces.append(trace)

Out [6]:

Now that we have our traces, we can also plot them using Bokeh:

In [7]:

import holoviews as hv
hv.extension('bokeh')
hv.Curve(traces[0].wave).opts(height=600, width=600)

Out [7]: