Hi.
I began discussing weird behaviour of CW Husky specific to the SCA attacks against hardware AES implementation in this thread CW Husky and CW Lite capture different traces - #13 by NewDwarf
…but feedback didn’t help me to fix the problem.
Moreover, collecting more and more traces (up to 80K) makes impossible to guess any byte of the round key even if exact leak samples are used to guess the key.
I decided to take the arbitrary signal generator, produce the 7.37 Mhz sine wave (pretty comfort conditions for any hardware) and pass it to the Husky’s “Measurement Pos” SMA port.
So, the scenario is:
- Husky captures the stable continuous sine wave. Capture is triggered by regular communication with the target board.
- Captured traces of the sine wave are synchronized by SAD for better visualization.
- Captured traces are visualized.
The input sine wave has 1 Vpp magnitude and it is 7.37 Mhz. The coax cable is terminated by SMA connector from one side and BNC from another side, impedance 50 Ohm.
An oscilloscope displays nice and stable sine wave.
Following script is used to capture the sine wave:
import chipwhisperer as cw
import chipwhisperer.analyzer as cwa
from bokeh.plotting import figure, show
from bokeh.io import output_notebook
from bokeh.palettes import brewer
import time
from tqdm import tqdm
scope = cw.scope()
target = cw.target(scope, cw.targets.SimpleSerial2)
time.sleep(0.05)
scope.default_setup()
time.sleep(0.05)
scope.io.nrst = 'low'
time.sleep(0.05)
scope.io.nrst = 'high_z'
scope.gain.db = 10
scope.adc.samples = 1148
scope.adc.offset = 0
scope.adc.basic_mode = "rising_edge"
scope.clock.adc_mul = 4
scope.clock.reset_adc()
assert (scope.clock.adc_locked), "ADC failed to lock"
project = cw.create_project("traces/tmp_hw_aes.cwp", overwrite=True)
ktp = cw.ktp.Basic()
N = 200
for i in tqdm(range(N)):
key, text = ktp.next()
trace = cw.capture_trace(scope, target, text, key)
if trace is None:
continue
project.traces.append(trace)
print(scope.adc.trig_count)
scope.dis()
target.dis()
resync_traces = cwa.preprocessing.ResyncSAD(project)
resync_traces.ref_trace = 0
resync_traces.target_window = (3, 7)
resync_traces.max_shift = 3
resync_analyzer = resync_traces.preprocess()
p = figure(sizing_mode='scale_width', plot_height=300, x_range=(0, 20))
xrange = range(0, len(resync_analyzer.waves[0]))
for i in range(0, 15):
p.line(xrange, resync_analyzer.waves[i], line_color="red")
for i in range(50, 15):
p.line(xrange, resync_analyzer.waves[i], line_color="green")
for i in range(100, 115):
p.line(xrange, resync_analyzer.waves[i], line_color="blue")
show(p)
The script gives such output:
I am not a digital signal processing expert but I would expect to see single blue line with tiny jitter.
Produced by Husky’s ADC output has different amplitude, very high jitter and kind of phase shifting.
The output definitely doesn’t look perfect.
And ultimately, an explanation of why great number of collected power traces brings a lot of noise so that any byte of the round key cannot be guessed.
Below is visualization of 20000 traces of the stable syne wave 7.37 Mhz
Here, I would expect to see thin red line instead of this noisy picture.