As of August 2020 the site you are on (wiki.newae.com) is deprecated, and content is now at rtfm.newae.com. |
Difference between revisions of "MATLAB Control of CW-Lite"
(→Running Examples) |
m (Removed irrelevant sentence) |
||
(6 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{Warningbox|For the older V3.x tools, see [[V3:MATLAB Control of CW-Lite]]}} | ||
+ | |||
The following is designed to demonstrate how to control the CW-Lite directly from MATLAB. | The following is designed to demonstrate how to control the CW-Lite directly from MATLAB. | ||
Line 5: | Line 7: | ||
This system relies on the Mathworks Python interface, which is built in as of R2014B. See [https://www.mathworks.com/help/matlab/examples/call-python-from-matlab.html MathWorks Reference Page] for more details. | This system relies on the Mathworks Python interface, which is built in as of R2014B. See [https://www.mathworks.com/help/matlab/examples/call-python-from-matlab.html MathWorks Reference Page] for more details. | ||
− | The code is currently held in a separate | + | The code is currently held in a separate [https://github.com/newaetech/cw-apiexample1/tree/master/matlab repository]. You'll have to clone that repository (or use the download link inside of GITHub) to copy the files into your own local working directory. |
== Python/ChipWhisperer Setup == | == Python/ChipWhisperer Setup == | ||
Line 43: | Line 45: | ||
== Running Examples == | == Running Examples == | ||
+ | To run the examples, you will need to ensure you set the MATLAB working directory to the location of the .m script files. | ||
− | + | Since the new CW 4,0 API exposes the internals of chipwhisperer the easiest way to get access to the chipwhisperer module in MATLAB is to use this API. Run this command in MATLAB. | |
+ | <syntaxhighlight lang=matlab> | ||
+ | >> [cw, scope, target] = cwconnect() | ||
+ | </syntaxhighlight> | ||
+ | or | ||
+ | <pre> | ||
+ | >> [cw, scope, target] = cwconnect(int64(1250), int64(3000)) | ||
+ | </pre> | ||
+ | where the first argument is the default offset, and the second argument is default number of samples. This command should return the 4.0 API, scope object, and target object, each having their own interface. | ||
− | + | If this works it should print the information about the 'cw', 'scope' and 'target' object: | |
+ | <syntaxhighlight> | ||
+ | cw = | ||
− | + | Python module with properties: | |
− | + | analyzer_gui: [1×1 py.function] | |
+ | analyzer: [1×1 py.module] | ||
+ | cwa: [1×1 py.module] | ||
+ | CWCoreAPI: [1×1 py.type] | ||
+ | cwtarget: [1×1 py.type] | ||
+ | captureN: [1×1 py.chipwhisperer.gui_only] | ||
+ | updateUI: [1×1 py.function] | ||
+ | common: [1×1 py.module] | ||
+ | gui: [1×1 py.type] | ||
+ | getLastTextin: [1×1 py.chipwhisperer.gui_only] | ||
+ | AcquisitionController: [1×1 py.classobj] | ||
+ | gui_only: [1×1 py.type] | ||
+ | acquisition_controller: [1×1 py.function] | ||
+ | capture_gui: [1×1 py.function] | ||
+ | Parameter: [1×1 py.type] | ||
+ | getLastExpected: [1×1 py.chipwhisperer.gui_only] | ||
+ | auxList: [1×1 py.chipwhisperer.gui_only] | ||
+ | AcqKeyTextPattern_Basic: [1×1 py.type] | ||
+ | trace_container_native: [1×1 py.module] | ||
+ | os: [1×1 py.module] | ||
+ | ScopeTemplate: [1×1 py.type] | ||
+ | getLastTextout: [1×1 py.chipwhisperer.gui_only] | ||
+ | target: [1×1 py.function] | ||
+ | openProject: [1×1 py.function] | ||
+ | BasicKtp: [1×1 py.type] | ||
+ | cwc: [1×1 py.module] | ||
+ | cw_bytearray: [1×1 py.type] | ||
+ | TargetTemplate: [1×1 py.type] | ||
+ | createProject: [1×1 py.function] | ||
+ | cwhardware: [1×1 py.type] | ||
+ | project: [1×1 py.module] | ||
+ | getLastKey: [1×1 py.chipwhisperer.gui_only] | ||
+ | scope: [1×1 py.function] | ||
+ | hardware: [1×1 py.module] | ||
+ | capture: [1×1 py.module] | ||
− | + | <module 'chipwhisperer' from 'c:\chipwhisperer\software\chipwhisperer\__init__.pyc'> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | scope = | ||
+ | |||
+ | Python OpenADC with properties: | ||
+ | |||
+ | connectStatus: [1×1 py.chipwhisperer.common.utils.util.Observable] | ||
+ | scopetype: [1×1 py.chipwhisperer.capture.scopes.openadc_interface.naeusbchip.OpenADCInterface_NAEUSBChip] | ||
+ | digitalPattern: [1×1 py.NoneType] | ||
+ | adc: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.TriggerSettings] | ||
+ | params: [1×1 py.chipwhisperer.common.utils.parameter.Parameter] | ||
+ | qtadc: [1×1 py.chipwhisperer.capture.scopes._qt.OpenADCQt] | ||
+ | advancedSettings: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.ChipWhispererExtra] | ||
+ | trigger: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.TriggerSettings] | ||
+ | refreshTimer: [1×1 py.chipwhisperer.common.utils.timer.FakeQTimer] | ||
+ | glitch: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererGlitch.GlitchSettings] | ||
+ | advancedSAD: [1×1 py.NoneType] | ||
+ | clock: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.ClockSettings] | ||
+ | gain: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.GainSettings] | ||
+ | channels: [1×1 py.list] | ||
+ | io: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.GPIOSettings] | ||
+ | |||
+ | cwlite Device | ||
+ | gain = | ||
+ | mode = low | ||
+ | gain = 45 | ||
+ | db = 22.50390625 | ||
+ | adc = | ||
+ | state = False | ||
+ | basic_mode = rising_edge | ||
+ | timeout = 2 | ||
+ | offset = 1250 | ||
+ | presamples = 0 | ||
+ | samples = 3000 | ||
+ | decimate = 1 | ||
+ | trig_count = 173067711 | ||
+ | clock = | ||
+ | adc_src = clkgen_x4 | ||
+ | adc_phase = 0 | ||
+ | adc_freq = 4067562 | ||
+ | adc_rate = 4067562 | ||
+ | adc_locked = True | ||
+ | freq_ctr = 0 | ||
+ | freq_ctr_src = extclk | ||
+ | clkgen_src = system | ||
+ | extclk_freq = 10000000 | ||
+ | clkgen_mul = 2 | ||
+ | clkgen_div = 26 | ||
+ | clkgen_freq = 7384615 | ||
+ | clkgen_locked = True | ||
+ | trigger = | ||
+ | triggers = tio4 | ||
+ | module = basic | ||
+ | io = | ||
+ | tio1 = serial_rx | ||
+ | tio2 = serial_tx | ||
+ | tio3 = high_z | ||
+ | tio4 = high_z | ||
+ | pdid = high_z | ||
+ | pdic = high_z | ||
+ | nrst = high_z | ||
+ | glitch_hp = False | ||
+ | glitch_lp = False | ||
+ | extclk_src = hs1 | ||
+ | hs2 = clkgen | ||
+ | target_pwr = True | ||
+ | glitch = | ||
+ | clk_src = target | ||
+ | width = 10.15625 | ||
+ | width_fine = 0 | ||
+ | offset = 10.15625 | ||
+ | offset_fine = 0 | ||
+ | trigger_src = manual | ||
+ | arm_timing = after_scope | ||
+ | ext_offset = 0 | ||
+ | repeat = 1 | ||
+ | output = clock_xor | ||
+ | |||
+ | |||
+ | |||
+ | target = | ||
+ | |||
+ | Python SimpleSerial with properties: | ||
+ | |||
+ | baud: 38400 | ||
+ | fixed_mask: [1×0 py.str] | ||
+ | go_cmd: [1×9 py.str] | ||
+ | init_cmd: [1×0 py.str] | ||
+ | input_cmd: [1×0 py.str] | ||
+ | input_len: 16 | ||
+ | key_cmd: [1×8 py.str] | ||
+ | key_len: 16 | ||
+ | mask_cmd: [1×9 py.str] | ||
+ | mask_enabled: 0 | ||
+ | mask_len: 18 | ||
+ | mask_type: [1×5 py.str] | ||
+ | output_cmd: [1×13 py.str] | ||
+ | output_len: 16 | ||
+ | connectStatus: [1×1 py.chipwhisperer.common.utils.util.Observable] | ||
+ | newInputData: [1×1 py.chipwhisperer.common.utils.util.Signal] | ||
+ | key: [1×0 py.str] | ||
+ | ser: [1×1 py.chipwhisperer.capture.targets.simpleserial_readers.cwlite.SimpleSerial_ChipWhispererLite] | ||
+ | params: [1×1 py.chipwhisperer.common.utils.parameter.Parameter] | ||
+ | outputlength: 16 | ||
+ | protver: [1×0 py.str] | ||
+ | initmask: [1×53 py.str] | ||
+ | protformat: [1×3 py.str] | ||
+ | maskEnabled: 0 | ||
+ | keylength: 16 | ||
+ | outstanding_ack: 0 | ||
+ | textlength: 16 | ||
+ | input: [1×0 py.str] | ||
+ | presets: [1×1 py.dict] | ||
+ | masklength: 18 | ||
+ | |||
+ | key_len = 16 | ||
+ | input_len = 16 | ||
+ | output_len = 16 | ||
+ | mask_len = 18 | ||
+ | init_cmd = | ||
+ | key_cmd = k$KEY$\n | ||
+ | input_cmd = | ||
+ | go_cmd = p$TEXT$\n | ||
+ | output_cmd = r$RESPONSE$\n | ||
+ | mask_cmd = m$MASK$\n | ||
+ | mask_enabled = False | ||
+ | mask_type = fixed | ||
+ | fixed_mask = | ||
+ | baud = 38400 | ||
+ | protver = | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | If this FAILS, you may need to simply unplug/replug the ChipWhisperer-Lite. You may not have closed the connection from the previous test. | ||
+ | |||
+ | == Interfacing with AES == | ||
+ | What you probably want to do is capture a trace during AES encryption, to test your side channel skills in MATLAB. You can do this by running | ||
+ | <syntaxhighlight lang=matlab> | ||
+ | >> [textout, trace] = measure_AES(scope, target, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15],[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]) | ||
+ | </syntaxhighlight> | ||
+ | This will return the cipher-text and the power trace. | ||
− | + | == 4.0 API Notes == | |
+ | Once the <code>cwconnect.m</code> function is executed you have access to the scope and target options, which are part of the new exposed API in <code>chipwhisperer</code>. To list the properties that are available type this inside your MATLAB interpreter: | ||
+ | <pre> | ||
+ | >> scope | ||
+ | </pre> | ||
+ | This should print the MATLAb output for the scope object but python also prints the attributes you can change and customize. The output should look like this: | ||
+ | <pre> | ||
+ | scope = | ||
− | + | Python OpenADC with properties: | |
− | + | connectStatus: [1×1 py.chipwhisperer.common.utils.util.Observable] | |
+ | scopetype: [1×1 py.chipwhisperer.capture.scopes.openadc_interface.naeusbchip.OpenADCInterface_NAEUSBChip] | ||
+ | digitalPattern: [1×1 py.NoneType] | ||
+ | adc: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.TriggerSettings] | ||
+ | params: [1×1 py.chipwhisperer.common.utils.parameter.Parameter] | ||
+ | qtadc: [1×1 py.chipwhisperer.capture.scopes._qt.OpenADCQt] | ||
+ | advancedSettings: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.ChipWhispererExtra] | ||
+ | trigger: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.TriggerSettings] | ||
+ | refreshTimer: [1×1 py.chipwhisperer.common.utils.timer.FakeQTimer] | ||
+ | glitch: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererGlitch.GlitchSettings] | ||
+ | advancedSAD: [1×1 py.NoneType] | ||
+ | clock: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.ClockSettings] | ||
+ | gain: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.GainSettings] | ||
+ | channels: [1×1 py.list] | ||
+ | io: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.GPIOSettings] | ||
− | + | cwlite Device | |
+ | gain = | ||
+ | mode = low | ||
+ | gain = 45 | ||
+ | db = 22.50390625 | ||
+ | adc = | ||
+ | state = False | ||
+ | basic_mode = rising_edge | ||
+ | timeout = 2 | ||
+ | offset = 1250 | ||
+ | presamples = 0 | ||
+ | samples = 3000 | ||
+ | decimate = 1 | ||
+ | trig_count = 173067711 | ||
+ | clock = | ||
+ | adc_src = clkgen_x4 | ||
+ | adc_phase = 0 | ||
+ | adc_freq = 29538471 | ||
+ | adc_rate = 29538471 | ||
+ | adc_locked = True | ||
+ | freq_ctr = 0 | ||
+ | freq_ctr_src = extclk | ||
+ | clkgen_src = system | ||
+ | extclk_freq = 10000000 | ||
+ | clkgen_mul = 2 | ||
+ | clkgen_div = 26 | ||
+ | clkgen_freq = 7384615 | ||
+ | clkgen_locked = True | ||
+ | trigger = | ||
+ | triggers = tio4 | ||
+ | module = basic | ||
+ | io = | ||
+ | tio1 = serial_rx | ||
+ | tio2 = serial_tx | ||
+ | tio3 = high_z | ||
+ | tio4 = high_z | ||
+ | pdid = high_z | ||
+ | pdic = high_z | ||
+ | nrst = high_z | ||
+ | glitch_hp = False | ||
+ | glitch_lp = False | ||
+ | extclk_src = hs1 | ||
+ | hs2 = clkgen | ||
+ | target_pwr = True | ||
+ | glitch = | ||
+ | clk_src = target | ||
+ | width = 10.15625 | ||
+ | width_fine = 0 | ||
+ | offset = 10.15625 | ||
+ | offset_fine = 0 | ||
+ | trigger_src = manual | ||
+ | arm_timing = after_scope | ||
+ | ext_offset = 0 | ||
+ | repeat = 1 | ||
+ | output = clock_xor | ||
+ | </pre> | ||
+ | So to change the offset we set earlier with the matlab function we could do this: | ||
+ | <pre> | ||
+ | >> scope.adc.offset = int64(1500); | ||
+ | </pre> | ||
+ | The <code>int64()</code> function is needed so matlab does not pass a string through to the python function. We can see that the value has now changed by running: | ||
+ | <pre> | ||
+ | >> scope.adc.offset | ||
+ | </pre> | ||
+ | with this result: | ||
+ | <pre> | ||
+ | ans = | ||
− | + | int64 | |
− | + | 1500 | |
+ | </pre> | ||
+ | <b>Note: it is good practice to check what type the attribute of the scope and target objects is, so you can assign the correct type using MATALB's int64()...etc functions.</b> | ||
− | + | === Manual 4.0 API Usage === | |
+ | To import the chipwhisperer python module into MATLAB run | ||
+ | <pre> | ||
+ | >> cw = py.importlib.import_module('chipwhisperer') | ||
+ | </pre> | ||
+ | This will work as long as you have the <code>chipwhisperer</code> module on your python path or system path. You can actually interact directly with the 'cw' as in Python, just as you would after running <code> import chipwhisperer as cw </code> in Python. So you can initialize a scope and a target: | ||
+ | <syntaxhighlight lang=matlab> | ||
+ | >> scope = cw.scope() | ||
+ | >> target = cw.target(scope) | ||
+ | </syntaxhighlight> | ||
+ | Do some fun things with your chipwhisperer tool, like follow a wiki tutorial (you will just have to implement the examples with MATLAB instead), and close the connection when you are done: | ||
+ | <syntaxhighlight lang=matlab> | ||
+ | >> scope.dis() | ||
+ | >> target.dis() | ||
+ | </syntaxhighlight> | ||
− | + | == Usage Notes == | |
− | + | By default the CW-Lite starts recording at 1250 samples after the trigger (1250 / 4 = 312.5 target device clock cyles), and records for 3000 samples (3000 / 4 = 750 target device clock cycles). These are suitable for the example AES in C, but you may need to reduce the offset if running AES in assembly for example. | |
− | + | The ChipWhisperer-Lite has a maximum capture length of about 24000 samples. The maximum offset is 4294967294. |
Latest revision as of 08:25, 9 March 2018
For the older V3.x tools, see V3:MATLAB Control of CW-Lite
The following is designed to demonstrate how to control the CW-Lite directly from MATLAB.
Contents
About MATLAB to Python Interface
This system relies on the Mathworks Python interface, which is built in as of R2014B. See MathWorks Reference Page for more details.
The code is currently held in a separate repository. You'll have to clone that repository (or use the download link inside of GITHub) to copy the files into your own local working directory.
Python/ChipWhisperer Setup
You will need to first install Python 2.7 + ChipWhisperer. Note you'll need match the type of Python to your MATLAB install (i.e., 64-bit Python if using 64-bit MATLAB). Specific steps follow:
- Download WinPython 2.7.10.3, most likely you will require the 64-bit version (most recent MATLAB installs will be 64-bit).
- Run the installer - it will actually just extract this somewhere, I suggest to use a location such as c:\WinPython-64bit-2.7.10.3 rather than the default which will just install in a subdirectory of whereever you downloaded the installer to.
- Run the 'WinPython Command Prompt' - this will be in the directory you installed WinPython to.
- Run
pip install chipwhisperer
in the WinPython prompt which should install ChipWhisperer. - Plug in CW-Lite, when prompted for drivers you'll have to download the driver zip-file and extract that somewhere, then point the installer to this location.
- Once drivers are installed, you should be able to run the examples from the WinPython command prompt. To do run the command
python
to start Python interpreter, then run:
>>> import chipwhisperer >>> chipwhisperer.capture_gui()
- This should open the capture GUI. From the 'Project' and 'Example Scripts' menu, select 'ChipWhisperer-Lite: AES SimpleSerial on XMEGA'.
- Hopefully you see some waveforms show up on the screen!
MATLAB Setup
MATLAB will need to be told about your Python location most likely. You can check this by seeing the value of the pyversion variable at the MATLAB command prompt:
>> pyversion version: executable: library: home: isloaded: 0
This indicates it does not have a valid Python environment. Simply point to your Python binary:
>> pyversion 'C:\WinPython-64bit-2.7.9.5\python-2.7.9.amd64\python.exe'
Where you will need to adjust the path for your local version/install. You can confirm with pyversion this worked. You shouldn't need to do any more setup now, it should remember this Python environment.
Running Examples
To run the examples, you will need to ensure you set the MATLAB working directory to the location of the .m script files.
Since the new CW 4,0 API exposes the internals of chipwhisperer the easiest way to get access to the chipwhisperer module in MATLAB is to use this API. Run this command in MATLAB.
>> [cw, scope, target] = cwconnect()
or
>> [cw, scope, target] = cwconnect(int64(1250), int64(3000))
where the first argument is the default offset, and the second argument is default number of samples. This command should return the 4.0 API, scope object, and target object, each having their own interface.
If this works it should print the information about the 'cw', 'scope' and 'target' object:
cw =
Python module with properties:
analyzer_gui: [1×1 py.function]
analyzer: [1×1 py.module]
cwa: [1×1 py.module]
CWCoreAPI: [1×1 py.type]
cwtarget: [1×1 py.type]
captureN: [1×1 py.chipwhisperer.gui_only]
updateUI: [1×1 py.function]
common: [1×1 py.module]
gui: [1×1 py.type]
getLastTextin: [1×1 py.chipwhisperer.gui_only]
AcquisitionController: [1×1 py.classobj]
gui_only: [1×1 py.type]
acquisition_controller: [1×1 py.function]
capture_gui: [1×1 py.function]
Parameter: [1×1 py.type]
getLastExpected: [1×1 py.chipwhisperer.gui_only]
auxList: [1×1 py.chipwhisperer.gui_only]
AcqKeyTextPattern_Basic: [1×1 py.type]
trace_container_native: [1×1 py.module]
os: [1×1 py.module]
ScopeTemplate: [1×1 py.type]
getLastTextout: [1×1 py.chipwhisperer.gui_only]
target: [1×1 py.function]
openProject: [1×1 py.function]
BasicKtp: [1×1 py.type]
cwc: [1×1 py.module]
cw_bytearray: [1×1 py.type]
TargetTemplate: [1×1 py.type]
createProject: [1×1 py.function]
cwhardware: [1×1 py.type]
project: [1×1 py.module]
getLastKey: [1×1 py.chipwhisperer.gui_only]
scope: [1×1 py.function]
hardware: [1×1 py.module]
capture: [1×1 py.module]
<module 'chipwhisperer' from 'c:\chipwhisperer\software\chipwhisperer\__init__.pyc'>
scope =
Python OpenADC with properties:
connectStatus: [1×1 py.chipwhisperer.common.utils.util.Observable]
scopetype: [1×1 py.chipwhisperer.capture.scopes.openadc_interface.naeusbchip.OpenADCInterface_NAEUSBChip]
digitalPattern: [1×1 py.NoneType]
adc: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.TriggerSettings]
params: [1×1 py.chipwhisperer.common.utils.parameter.Parameter]
qtadc: [1×1 py.chipwhisperer.capture.scopes._qt.OpenADCQt]
advancedSettings: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.ChipWhispererExtra]
trigger: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.TriggerSettings]
refreshTimer: [1×1 py.chipwhisperer.common.utils.timer.FakeQTimer]
glitch: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererGlitch.GlitchSettings]
advancedSAD: [1×1 py.NoneType]
clock: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.ClockSettings]
gain: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.GainSettings]
channels: [1×1 py.list]
io: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.GPIOSettings]
cwlite Device
gain =
mode = low
gain = 45
db = 22.50390625
adc =
state = False
basic_mode = rising_edge
timeout = 2
offset = 1250
presamples = 0
samples = 3000
decimate = 1
trig_count = 173067711
clock =
adc_src = clkgen_x4
adc_phase = 0
adc_freq = 4067562
adc_rate = 4067562
adc_locked = True
freq_ctr = 0
freq_ctr_src = extclk
clkgen_src = system
extclk_freq = 10000000
clkgen_mul = 2
clkgen_div = 26
clkgen_freq = 7384615
clkgen_locked = True
trigger =
triggers = tio4
module = basic
io =
tio1 = serial_rx
tio2 = serial_tx
tio3 = high_z
tio4 = high_z
pdid = high_z
pdic = high_z
nrst = high_z
glitch_hp = False
glitch_lp = False
extclk_src = hs1
hs2 = clkgen
target_pwr = True
glitch =
clk_src = target
width = 10.15625
width_fine = 0
offset = 10.15625
offset_fine = 0
trigger_src = manual
arm_timing = after_scope
ext_offset = 0
repeat = 1
output = clock_xor
target =
Python SimpleSerial with properties:
baud: 38400
fixed_mask: [1×0 py.str]
go_cmd: [1×9 py.str]
init_cmd: [1×0 py.str]
input_cmd: [1×0 py.str]
input_len: 16
key_cmd: [1×8 py.str]
key_len: 16
mask_cmd: [1×9 py.str]
mask_enabled: 0
mask_len: 18
mask_type: [1×5 py.str]
output_cmd: [1×13 py.str]
output_len: 16
connectStatus: [1×1 py.chipwhisperer.common.utils.util.Observable]
newInputData: [1×1 py.chipwhisperer.common.utils.util.Signal]
key: [1×0 py.str]
ser: [1×1 py.chipwhisperer.capture.targets.simpleserial_readers.cwlite.SimpleSerial_ChipWhispererLite]
params: [1×1 py.chipwhisperer.common.utils.parameter.Parameter]
outputlength: 16
protver: [1×0 py.str]
initmask: [1×53 py.str]
protformat: [1×3 py.str]
maskEnabled: 0
keylength: 16
outstanding_ack: 0
textlength: 16
input: [1×0 py.str]
presets: [1×1 py.dict]
masklength: 18
key_len = 16
input_len = 16
output_len = 16
mask_len = 18
init_cmd =
key_cmd = k$KEY$\n
input_cmd =
go_cmd = p$TEXT$\n
output_cmd = r$RESPONSE$\n
mask_cmd = m$MASK$\n
mask_enabled = False
mask_type = fixed
fixed_mask =
baud = 38400
protver =
If this FAILS, you may need to simply unplug/replug the ChipWhisperer-Lite. You may not have closed the connection from the previous test.
Interfacing with AES
What you probably want to do is capture a trace during AES encryption, to test your side channel skills in MATLAB. You can do this by running
>> [textout, trace] = measure_AES(scope, target, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15],[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15])
This will return the cipher-text and the power trace.
4.0 API Notes
Once the cwconnect.m
function is executed you have access to the scope and target options, which are part of the new exposed API in chipwhisperer
. To list the properties that are available type this inside your MATLAB interpreter:
>> scope
This should print the MATLAb output for the scope object but python also prints the attributes you can change and customize. The output should look like this:
scope = Python OpenADC with properties: connectStatus: [1×1 py.chipwhisperer.common.utils.util.Observable] scopetype: [1×1 py.chipwhisperer.capture.scopes.openadc_interface.naeusbchip.OpenADCInterface_NAEUSBChip] digitalPattern: [1×1 py.NoneType] adc: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.TriggerSettings] params: [1×1 py.chipwhisperer.common.utils.parameter.Parameter] qtadc: [1×1 py.chipwhisperer.capture.scopes._qt.OpenADCQt] advancedSettings: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.ChipWhispererExtra] trigger: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.TriggerSettings] refreshTimer: [1×1 py.chipwhisperer.common.utils.timer.FakeQTimer] glitch: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererGlitch.GlitchSettings] advancedSAD: [1×1 py.NoneType] clock: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.ClockSettings] gain: [1×1 py.chipwhisperer.capture.scopes._OpenADCInterface.GainSettings] channels: [1×1 py.list] io: [1×1 py.chipwhisperer.capture.scopes.cwhardware.ChipWhispererExtra.GPIOSettings] cwlite Device gain = mode = low gain = 45 db = 22.50390625 adc = state = False basic_mode = rising_edge timeout = 2 offset = 1250 presamples = 0 samples = 3000 decimate = 1 trig_count = 173067711 clock = adc_src = clkgen_x4 adc_phase = 0 adc_freq = 29538471 adc_rate = 29538471 adc_locked = True freq_ctr = 0 freq_ctr_src = extclk clkgen_src = system extclk_freq = 10000000 clkgen_mul = 2 clkgen_div = 26 clkgen_freq = 7384615 clkgen_locked = True trigger = triggers = tio4 module = basic io = tio1 = serial_rx tio2 = serial_tx tio3 = high_z tio4 = high_z pdid = high_z pdic = high_z nrst = high_z glitch_hp = False glitch_lp = False extclk_src = hs1 hs2 = clkgen target_pwr = True glitch = clk_src = target width = 10.15625 width_fine = 0 offset = 10.15625 offset_fine = 0 trigger_src = manual arm_timing = after_scope ext_offset = 0 repeat = 1 output = clock_xor
So to change the offset we set earlier with the matlab function we could do this:
>> scope.adc.offset = int64(1500);
The int64()
function is needed so matlab does not pass a string through to the python function. We can see that the value has now changed by running:
>> scope.adc.offset
with this result:
ans = int64 1500
Note: it is good practice to check what type the attribute of the scope and target objects is, so you can assign the correct type using MATALB's int64()...etc functions.
Manual 4.0 API Usage
To import the chipwhisperer python module into MATLAB run
>> cw = py.importlib.import_module('chipwhisperer')
This will work as long as you have the chipwhisperer
module on your python path or system path. You can actually interact directly with the 'cw' as in Python, just as you would after running import chipwhisperer as cw
in Python. So you can initialize a scope and a target:
>> scope = cw.scope()
>> target = cw.target(scope)
Do some fun things with your chipwhisperer tool, like follow a wiki tutorial (you will just have to implement the examples with MATLAB instead), and close the connection when you are done:
>> scope.dis()
>> target.dis()
Usage Notes
By default the CW-Lite starts recording at 1250 samples after the trigger (1250 / 4 = 312.5 target device clock cyles), and records for 3000 samples (3000 / 4 = 750 target device clock cycles). These are suitable for the example AES in C, but you may need to reduce the offset if running AES in assembly for example.
The ChipWhisperer-Lite has a maximum capture length of about 24000 samples. The maximum offset is 4294967294.