SOLUTION WITH SIMULATION: Part 2, Topic 1, Lab B: Power Analysis for Password Bypass¶
NOTE: This lab references some (commercial) training material on ChipWhisperer.io. You can freely execute and use the lab per the open-source license (including using it in your own courses if you distribute similarly), but you must maintain notice about this source location. Consider joining our training course to enjoy the full experience.
SUMMARY: This tutorial will introduce you to breaking devices by determining when a device is performing certain operations. Our target device will be performing a simple password check, and we will demonstrate how to perform a basic power analysis.
LEARNING OUTCOMES:
- How power can be used to determine timing information.
- Plotting multiple iterations while varying input data to find interesting locations.
- Using difference of waveforms to find interesting locations.
- Performing power captures with ChipWhisperer hardware (hardware only)
Prerequisites¶
Hold up! Before you continue, check you've done the following tutorials:
- ☑ Jupyter Notebook Intro (you should be OK with plotting & running blocks).
- ☑ SCA101 Intro (you should have an idea of how to get hardware-specific versions running).
Power Trace Gathering¶
At this point you've got to insert code to perform the power trace capture. There are two options here:
- Capture from physical device.
- Read from a file.
You get to choose your adventure - see the two notebooks with the same name of this, but called (SIMULATED)
or (HARDWARE)
to continue. Inside those notebooks you should get some code to copy into the following section, which will define the capture function.
Be sure you get the "✔️ OK to continue!"
print once you run the next cell, otherwise things will fail later on!
Choose your setup options here:
SCOPETYPE='NONE'
PLATFORM='NONE'
CRYPTO_TARGET='NONE'
VERSION='SIMULATED'
allowable_exceptions = None
SS_VER = 'SS_VER_2_1'
if VERSION == 'HARDWARE':
%run "Lab 2_1B - Power Analysis for Password Bypass (HARDWARE).ipynb"
elif VERSION == 'SIMULATED':
%run "Lab 2_1B - Power Analysis for Password Bypass (SIMULATED).ipynb"
✔️ OK to continue!
trace_test = cap_pass_trace("h\n")
#Basic sanity check
assert(len(trace_test) == 3000)
print("✔️ OK to continue!")
✔️ OK to continue!
Exploration¶
So what can we do with this? While first off - I'm going to cheat, and tell you that we have a preset password that starts with h
, and it's 5 characters long. But that's the only hint so far - what can you do? While first off, let's try plotting a comparison of h
to something else.
If you need a reminder of how to do a plot - see the matplotlib section of the Jupyter Introduction notebook.
The following cell shows you how to capture one power trace with h
sent as a password. From there:
- Try adding the plotting code and see what it looks like.
- Send different passwords to the device. We're only going to look at the difference between a password starting with
h
and something else right now. - Plot the different waveforms.
#Example - capture 'h' - end with newline '\n' as serial protocol expects that
trace_h = cap_pass_trace("h\n")
print(trace_h)
# ###################
# START SOLUTION
# ###################
cw.plot(cap_pass_trace("h\n")) * cw.plot(cap_pass_trace("0\n"))
# ###################
# END SOLUTION
# ###################
[-0.10571289 -0.29638672 -0.18969727 ... 0.00976562 0.05200195 0.09228516]
For reference, the output should look something like this:
If you are using the %matplotlib notebook
magic, you can zoom in at the start. What you want to notice is there is two code paths taken, depending on a correct or incorrect path. Here for example is a correct & incorrect character processed:
OK interesting -- what's next? Let's plot every possible password character we could send.
Our password implementation only recognizes characters in the list abcdefghijklmnopqrstuvwxyz0123456789
, so we're going to limit it to those valid characters for now.
Write some code in the following block that implements the following algorithm:
for CHARACTER in LIST_OF_VALID_CHARACTERS:
trace = cap_pass_trace(CHARACTER + "\n")
plot(trace)
The above isn't quite valid code - so massage it into place! You also may notice the traces are way too long - you might want to make a more narrow plot that only does the first say 500 samples of the power trace.
📝Plotting Note
If using matplotlib
for plotting, you might need to add a plt.figure()
at the start to make a new figure. Otherwise you might find your plot ends up in the figure above! If you don't see the plots, sometimes a plt.show()
is needed at the end.
# ###################
# START SOLUTION
# ###################
from tqdm.notebook import tqdm
fig = cw.plot()
for c in tqdm('abcdefghijklmnopqrstuvwxyz0123456789'):
trace = cap_pass_trace(c + "\n")
fig *= cw.plot(trace[0:1000])
fig
# ###################
# END SOLUTION
# ###################