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"

From ChipWhisperer Wiki
Jump to: navigation, search
(Updated the wiki for the changed MATLAB api)
m (link was showing a 1 not a word, fixed it)
Line 7: 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 repository at [https://github.com/newaetech/cw-apiexample1/tree/master/matlab]. 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.
+
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 ==

Revision as of 10:48, 1 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.

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:

  1. Download WinPython 2.7.10.3, most likely you will require the 64-bit version (most recent MATLAB installs will be 64-bit).
  2. 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.
  3. Run the 'WinPython Command Prompt' - this will be in the directory you installed WinPython to.
  4. Run pip install chipwhisperer in the WinPython prompt which should install ChipWhisperer.
  5. 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.
  6. 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()
  1. This should open the capture GUI. From the 'Project' and 'Example Scripts' menu, select 'ChipWhisperer-Lite: AES SimpleSerial on XMEGA'.
  2. 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. MATLAB seems to not find certain modules even if they are on the python path so just use pythons build in importlib, which MATLAB can find, letting python find the module for MATLAB. 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 have not 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.