Changes

MATLAB Control of CW-Lite

9,523 bytes added, 16:25, 9 March 2018
m
Removed irrelevant sentence
{{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.
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 repository at [https://github.com/newaetech/cw-apiexample1/tree/master/matlabrepository]. 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 ==
== 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.
To run Since the examplesnew CW 4, you will need 0 API exposes the internals of chipwhisperer the easiest way to get access to ensure you set the chipwhisperer module in MATLAB working directory 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 location first argument is the default offset, and the second argument is default number of samples. This command should return the 4.m script files0 API, scope object, and target object, each having their own interface. The following shows my example setup:
[[FileIf this works it should print the information about the 'cw', 'scope' and 'target' object:api_matlab_path.png]]<syntaxhighlight> cw =
The matlab files internally will reference a .py file in that same directory. You should be able to simply connect to the ChipWhisperer-Lite Python module with the followingproperties:
>> cw = cwconnect() 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]
If this works it should print the information about the <module 'cwchipwhisperer' objectfrom 'c:\chipwhisperer\software\chipwhisperer\__init__.pyc'>
cw =
scope =   Python CWCoreAPI 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.
sigNewProject: [1x1 py.chipwhisperer.common.utils.util.Signal]== Interfacing with AES == valid_aux: [1x1 pyWhat you probably want to do is capture a trace during AES encryption, to test your side channel skills in MATLAB.collections.OrderedDict]You can do this by running auxParam: [1x1 py.chipwhisperer.common.utils.parameter.Parameter]<syntaxhighlight lang=matlab> sigConnectStatus: >> [1x1 py.chipwhisperer.common.utils.util.Signaltextout, trace] sigNewTextResponse: = measure_AES(scope, target, [1x1 py.chipwhisperer.common.utils.util.Signal0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15] valid_attacks: ,[1x1 py.collections.OrderedDict0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]) sigTraceDone: [1x1 py.chipwhisperer.common.utils.util.Signal]</syntaxhighlight> traceParam: [1x1 pyThis will return the cipher-text and the power trace.chipwhisperer.common.utils.parameter.Parameter] executingScripts: [1x1 py.chipwhisperer.common.utils.util.Observable] scopeParam: [1x1 py.chipwhisperer.common.utils.parameter.Parameter] sigCampaignStart: [1x1 py.chipwhisperer.common.utils.util.Signal] sigNewInputData: [1x1 py.chipwhisperer.common.utils.util.Signal] params: [1x1 py.chipwhisperer.common.utils.parameter.Parameter] settings: [1x1 py.chipwhisperer.common.api.settings.Settings] valid_acqPatterns: [1x1 py.collections.OrderedDict] valid_scopes: [1x1 py.collections.OrderedDict] targetParam: [1x1 py.chipwhisperer.common.utils.parameter.Parameter] valid_traces: [1x1 py.collections.OrderedDict] valid_targets: [1x1 py.collections.OrderedDict] sigAttackChanged: [1x1 py.chipwhisperer.common.utils.util.Signal] sigCampaignDone: [1x1 py.chipwhisperer.common.utils.util.Signal] valid_preprocessingModules: [1x1 py.collections.OrderedDict]
== 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>.common.api.CWCoreAPI.CWCoreAPI 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 at 0x000000013312FD30but python also prints the attributes you can change and customize. The output should look like this:<pre>scope =
Python OpenADC with properties:
If this FAILS, you may need to simply unplug/replug the ChipWhisperer-Lite connectStatus: [1×1 py. You may have not closed the connection from the previous testchipwhisperer. Note you can actually interact directly with the 'cw' object as in Pythoncommon. For example we can get information about the current scope moduleutils.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> cw >> scope.getScopeadc.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 =
But you probably just want to run an AES test. To do this, simply perform the following: int64
[cipher 1500</pre><b>Note: it is good practice to check what type the attribute of the scope and target objects is, trace] = measure_AESso you can assign the correct type using MATALB's int64(cw, [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]);...etc functions.</b>
The measure_AES=== Manual 4.0 API Usage ===To import the chipwhisperer python module into MATLAB run<pre> >> cw = py.importlib.import_module('chipwhisperer') function passes both </pre>This will work as long as you have the plaintext <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 keya target:<syntaxhighlight lang=matlab> >> scope = cw. In this example they are both set 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 same array value. It returns the ciphertext resulting & examples with MATLAB instead), and close the power traceconnection when you are done:<syntaxhighlight lang=matlab> >> scope.dis() >> target.dis()</syntaxhighlight>
You can plot this power trace with:== Usage Notes ==
plotBy default the CW-Lite starts recording at 1250 samples after the trigger (trace1250 / 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.
[[File:matlab_plotThe ChipWhisperer-Lite has a maximum capture length of about 24000 samples. The maximum offset is 4294967294.png|400px]]