API

This is where the documentation for the public API functions, and classes lives.

Scope

The chipwhisperer.scope() API function creates and returns a scope object based on the supplied type argument. The are two currently supported classes for the type argument:

The OpenADC scope provides support for the ChipWhisperer Lite and the ChipWhisperer Pro, and the CWNano scope provides support for the ChipWhisperer Nano.

The scope object provides the API for configuring the capture side of the hardware (the scope). To create an instance of a connected scope use:

import chipwhisperer as cw
scope = cw.scope()

This will return a connected instance of one of the scope types or raise an exception. If no scope type is given the function will try to determine the scope type automatically.

scope(scope_type=None, name=None, sn=None, idProduct=None, bitstream=None, force=False, prog_speed=10000000, **kwargs) chipwhisperer.scope(type=None, sn=None)

Create a scope object and connect to it.

This function allows any type of scope to be created. By default, the object created is based on the attached hardware (OpenADC for CWLite/CW1200, CWNano for CWNano).

Scope Types:

If multiple chipwhisperers are connected, the serial number of the one you want to connect to can be specified by passing sn=<SERIAL_NUMBER>

Parameters
  • scope_type (Optional[Type[Union[OpenADC, CWNano]]]) – Scope type to connect to. Types can be found in chipwhisperer.scopes. If None, will try to detect the type of ChipWhisperer connected. Defaults to None.

  • name (Optional[str]) –

    model name of the ChipWhisperer that you want to connect to. Alternative to specifying the serial number when multiple ChipWhisperers, all of different type, are connected. Defaults to None. Valid values:

    • Lite

    • Pro

    • Husky

  • idProduct (Optional[int]) –

    idProduct of the ChipWhisperer that you want to connect to. Alternative to specifying the serial number when multiple ChipWhisperers, all of different type, are connected. Defaults to None. Valid values:

    • 0xace2: CW-Lite

    • 0xace3: CW-Pro

    • 0xace5: CW-Husky

  • sn (Optional[str]) – Serial number of ChipWhisperer that you want to connect to. sn is required if more than one ChipWhisperer of the same type is connected (i.e. two CWNano’s or a CWLite and CWPro). Defaults to None.

  • bitstream (Optional[str]) – Path to bitstream to program. If None, programs default bitstream. Optional, defaults to None. Ignored on Nano.

  • force (bool) – If True, always erase and program FPGA. If False, only erase and program FPGA if it is currently blank. Defaults to False. Ignored on Nano.

  • prog_speed (int) – Sets the FPGA programming speed for Lite, Pro, and Husky. If you get programming errors, try turning this down.

Return type

Union[OpenADC, CWNano]

Returns

Connected scope object.

Raises
  • OSError – Can be raised for issues connecting to the chipwhisperer, such as not having permission to access the USB device or no ChipWhisperer being connected.

  • Warning – Raised if multiple chipwhisperers are connected, but the type and/or the serial numbers are not specified

Changed in version 5.1: Added autodetection of scope_type

Changed in version 5.5: Added idProduct, name, bitstream, and force parameters.

OpenADC Scope

class OpenADC

OpenADC scope object.

This class contains the public API for the OpenADC hardware, including the ChipWhisperer Lite/ CW1200 Pro boards. It includes specific settings for each of these devices.

To connect to one of these devices, the easiest method is:

import chipwhisperer as cw
scope = cw.scope(type=scopes.OpenADC)

Some sane default settings are available via:

scope.default_setup()

This code will automatically detect an attached ChipWhisperer device and connect to it.

For more help about scope settings, try help() on each of the ChipWhisperer scope submodules (scope.gain, scope.adc, scope.clock, scope.io, scope.trigger, and scope.glitch):

If you have a CW1200 ChipWhisperer Pro, you have access to some additional features:

gain scope.gain
GainSettings.db scope.gain.db

The gain of the ChipWhisperer’s low-noise amplifier in dB. Ranges from -6.5 dB to 56 dB, depending on the amplifier settings.

Getter

Return the current gain in dB (float)

Setter

Set the gain level in dB

Raises

ValueError – if new gain is outside of [-6.5, 56]

Examples:

# reading and storing
gain_db = scope.gain.db

# setting
scope.gain.db = 20
GainSettings.mode scope.gain.mode

The current mode of the LNA.

The LNA can operate in two modes: low-gain or high-gain. Generally, the high-gain setting is better to use. Note that this value will be automatically updated if the dB gain is set.

Getter

Return the current gain mode (“low” or “high”)

Setter

Set the gain mode

Raises

ValueError – if mode not one of “low” or “high”

GainSettings.gain scope.gain.gain

The current LNA gain setting.

This gain is a dimensionless number in the range [0, 78]. Higher value causes higher gain in dB.

Note that this function is unnecessary - the dB gain can be set directly. This property is only here to help convert old scripts.

Getter

Return the current gain setting (int)

Setter

Set the gain

Raises

ValueError – if gain outside [0, 78]

Return type

int

adc scope.adc
TriggerSettings.state scope.adc.state

The current state of the trigger input.

This is a digital value (ie: high or low), which is some combination of the pins in the triggermux object. Read-only.

Getter: Return the current state (True or False).

TriggerSettings.stream_mode scope.adc.stream_mode

The ChipWhisperer’s streaming status. Only available on CW1200 and CW-Husky.

When stream mode is enabled, the ChipWhisperer sends back ADC data as soon as it is recorded. In this mode, there is no hardware limit on the maximum number of samples per trace (although Python may run out of memory when recording billions of points). However, there is a maximum streaming data rate, which is approximately 10 Msamp/s.

Note that no pre-trigger samples can be recorded when stream mode is enabled.

Getter

Return True if stream mode is enabled and False otherwise

Setter

Enable or disable stream mode

TriggerSettings.decimate scope.adc.decimate

The ADC downsampling factor.

This value instructs the ChipWhisperer to only record 1 sample in every <decimate>. In other words, if this value is set to 10, the sampling rate is set to 1/10th of the sampling clock.

This setting is helpful for recording very long operations or for reducing the sampling rate for streaming mode.

Getter

Return an integer with the current decimation factor

Setter

Set the decimation factor

Raises

ValueError – if the new factor is not positive

TriggerSettings.samples scope.adc.samples

The number of ADC samples to record in a single capture.

The maximum number of samples is hardware-dependent: - cwlite: 24400 - cw1200: 96000 - cwhusky: 131070

Getter

Return the current number of total samples (integer)

Setter

Set the number of samples to capture

Raises

ValueError – if number of samples is negative

TriggerSettings.timeout scope.adc.timeout

The number of seconds to wait before aborting a capture.

If no trigger event is detected before this time limit is up, the capture fails and no data is returned.

Getter

Return the number of seconds before a timeout (float)

Setter

Set the timeout in seconds

TriggerSettings.offset scope.adc.offset

The number of samples to wait before recording data after seeing a trigger event.

This offset is useful for long operations. For instance, if an encryption is 1 million samples long, it’s difficult to capture the entire power trace, but an offset can be used to skip to the end of the encryption.

The offset must be a 32 bit unsigned integer.

Getter

Return the current offset (integer)

Setter

Set a new offset

Raises

ValueError – if offset outside of range [0, 2**32)

TriggerSettings.presamples scope.adc.presamples

The number of samples to record from before the trigger event.

This setting must be a positive integer, and it cannot be larger than the number of samples. When streaming mode is enabled, this value is set to 0.

Getter

Return the current number of presamples

Setter

Set the number of presamples.

Raises

ValueError – if presamples is outside of range [0, samples]

TriggerSettings.basic_mode scope.adc.basic_mode

The type of event to use as a trigger.

Only applies to the ADC capture - the glitch module is always a rising edge trigger.

There are four possible types of trigger events:
  • “low”: triggers when line is low (logic 0)

  • “high”: triggers when line is high (logic 1)

  • “rising_edge”: triggers when line transitions from low to high

  • “falling_edge:” triggers when line transitions from high to low

Warning

This must be set to “rising_edge” if a trigger other than “basic” is used. The SAD/DecodeIO triggers will not work with any other setting!

Getter

Return the current trigger mode (one of the 4 above strings)

Setter

Set the trigger mode

Raises

ValueError – if value is not one of the allowed strings

TriggerSettings.trig_count scope.adc.trig_count

The number of samples that the trigger input was active.

This value indicates how long the trigger was high or low last time a trace was captured. It is the number of samples where the input was low (in “low” or “falling edge” modes) or high (in “high” or “rising edge” modes). Read-only.

This counter is not meaningful if the trigger is still active.

Getter

Return the last trigger duration (integer)

TriggerSettings.fifo_fill_mode scope.adc.fifo_fill_mode

The ADC buffer fill strategy - allows segmented usage for CW-lite and CW-pro.

Warning

THIS REQUIRES NEW FPGA BITSTREAM - NOT YET IN THE PYTHON.

Only the ‘Normal’ mode is well supported, the other modes can be used carefully.

For segmenting on CW-Husky, see ‘segments’ instead.

There are four possible modes:
  • “normal”: Trigger line & logic work as expected.

  • “enable”: Capture starts with rising edge, but writing samples

    is enabled by active-high state of trigger line.

  • “segment”: Capture starts with rising edge, and writes trigger.samples

    to buffer on each rising edge, stopping when the buffer is full. For this to work adc.samples must be a multiple of 3 (will be enforced by API).

Warning

The “enable” and “segment” modes requires you to fill the full buffer (~25K on CW-Lite, ~100K on CW-Pro). This requires you to ensure the physical trigger line will be high (enable mode) or toggle (segment mode) enough. The ChipWhisperer hardware will currently stall until the internal buffer is full, and future commands will fail.

Warning

adc.basic_mode must be set to “rising_edge” if a fill_mode other than “normal” is used. Bad things happen if not.

Getter

Return the current fifo fill mode (one of the 3 above strings)

Setter

Set the fifo fill mode

Raises

ValueError – if value is not one of the allowed strings

clock
Annotation

scope.clock

ClockSettings.adc_src scope.clock.adc_src

The clock source for the ADC module.

The ADC can be clocked by one of five possible sources:

  • “clkgen_x1”: CLKGEN output via DCM

  • “clkgen_x4”: CLKGEN output via DCM with x4 clk multiplier

  • “extclk_x1”: External clock input via DCM

  • “extclk_x4”: External clock input via DCM with x4 clk multiplier

  • “extclk_dir”: External clock input with no DCM

Getter

Return the current ADC clock source (one of five strings above)

Setter

Set the ADC clock source and reset the ADC DCM to lock it.

Raises

ValueError – if string not in valid settings

ClockSettings.adc_phase scope.clock.adc_phase

Fine adjustment for the ADC sampling point.

This setting moves the sampling point approximately 5 ns forward or backward, regardless of the sampling frequency. It may be helpful to improve the stability of the measurement.

The value of this setting is dimensionless and has a non-linear effect on the phase adjustment.

Getter

Return the current phase setting (integer) NOTE: This getter is currently broken due to an FPGA bug.

Setter

Set a new phase offset

Raises
  • ValueError – if offset not in [-32767, 32767] (Husky) or [-255, 255] (others)

  • TypeError – if offset not integer

ClockSettings.adc_freq scope.clock.adc_freq

The current frequency of the ADC clock in Hz. Read-only.

This clock frequency is derived from one of the ADC clock sources as described in adc_src.

Getter

Return the current frequency in MHz (float). May take up to 0.5s to stabilize after adc_locked is True.

ClockSettings.adc_rate scope.clock.adc_rate

The current sampling rate of the ADC clock in samples/s. Read-only.

Note that the sampling rate may be less than the clock frequency if the downsampling factor is greater than 1.

Getter

Return the current sampling rate in MS/s (float)

ClockSettings.adc_locked scope.clock.adc_locked

The current status of the ADC DCM. Read-only.

To try re-locking the ADC, see reset_adc().

Getter

Return whether the ADC DCM is locked (True or False)

ClockSettings.freq_ctr scope.clock.freq_ctr

The current frequency at the frequency counter in MHz. Read-only.

The frequency counter can be used to check the speed of the CLKGEN output or the EXTCLK input. This value shows the current frequency reading.

Getter

Return the current frequency in MHz (float)

ClockSettings.freq_ctr_src scope.clock.freq_ctr_src

The current input to the frequency counter.

There are two possible inputs to the frequency counter: - “clkgen”: The CLKGEN DCM output - “extclk”: The external input clock signal

Getter

Return the frequency counter input (one of the above strings)

Setter

Set the frequency counter source

Raises

ValueError – if source is not “clkgen” or “extclk”

ClockSettings.clkgen_src scope.clock.clkgen_src

The input source for the CLKGEN DCM.

This DCM can receive input from one of two places:

  • “extclk”: The external clock input

  • “system” or “internal”: The system clock (96 MHz)

Getter

Return the current CLKGEN input (either “extclk” or “system”)

Setter

Change the CLKGEN source and reset all the DCMs.

Raises

ValueError – if source is not one of three strings above

ClockSettings.extclk_freq scope.clock.extclk_freq

The input frequency from the EXTCLK source in Hz.

This value is used to help calculate the correct CLKGEN settings to obtain a desired output frequency when using EXTCLK as CLKGEN input. It is not a frequency counter - it is only helpful if the EXTCLK frequency is already known.

Getter

Return the last set EXTCLK frequency in MHz (int)

Setter

Update the EXTCLK frequency

ClockSettings.clkgen_mul scope.clock.clkgen_mul

The multiplier in the CLKGEN DCM.

This multiplier must be in the range [2, 256].

Getter

Return the current CLKGEN multiplier (integer)

Setter

Set a new CLKGEN multiplier.

ClockSettings.clkgen_div scope.clock.clkgen_div

The divider in the CLKGEN DCM.

This divider must be in the range [1, 256].

Getter

Return the current CLKGEN divider (integer)

Setter

Set a new CLKGEN divider.

ClockSettings.clkgen_freq scope.clock.clkgen_freq

The CLKGEN output frequency in Hz.

The CLKGEN module takes the input source and multiplies/divides it to get a faster or slower clock as desired. Minimum clock in practice is 3.2MHz.

Getter

Return the current calculated CLKGEN output frequency in Hz (float). Note that this is the theoretical frequency - use the freq counter to determine the actual output. May take up to 0.5s to stabilize after clkgen_locked is True.

Setter

Attempt to set a new CLKGEN frequency in Hz. When this value is set, all possible DCM multiply/divide settings are tested to find which is closest to the desired output speed. If EXTCLK is the CLKGEN source, the EXTCLK frequency must be properly set for this to work. Also, both DCMs are reset.

ClockSettings.clkgen_locked scope.clock.clkgen_locked

The current status of the CLKGEN DCM. Read-only.

Getter

Return whether the CLKGEN DCM is locked (True or False)

ClockSettings.reset_dcms()

Reset the CLKGEN DCM, then the ADC DCM.

This order is necessary because the ADC may depend on having a locked clock from the CLKGEN output.

io scope.io
GPIOSettings.tio1 scope.io.tio1

The function of the Target IO1 pin.

TIO1 can be used for the following functions:
  • “serial_rx”: UART input

  • “serial_tx”: UART output

  • “high_z” / None: High impedance input

  • “gpio_low” / False: Driven output: logic 0

  • “gpio_high” / True: Driven output: logic 1

  • “gpio_disabled”: Driven output: no effect

Default value is “serial_rx”.

Getter

Return one of the above strings

Setter

Set the Target IO1 mode.

Raises

ValueError – if new value is not one of the above modes

GPIOSettings.tio2 scope.io.tio2

The function of the Target IO2 pin.

TIO2 can be used for the following functions:
  • “serial_rx”: UART input

  • “serial_tx”: UART output

  • “high_z” / None: High impedance input

  • “gpio_low” / False: Driven output: logic 0

  • “gpio_high” / True: Driven output: logic 1

  • “gpio_disabled”: Driven output: no effect

Default value is “serial_tx”.

Getter

Return one of the above strings

Setter

Set the Target IO2 mode.

Raises

ValueError – if new value is not one of the above modes

GPIOSettings.tio3 scope.io.tio3

The function of the Target IO3 pin.

TIO3 can be used for the following functions:
  • “serial_rx”: UART input

  • “serial_tx”: UART output

  • “serial_tx_rx”: UART 1-wire I/O (for smartcards)

  • “high_z” / None: High impedance input

  • “gpio_low” / False: Driven output: logic 0

  • “gpio_high” / True: Driven output: logic 1

  • “gpio_disabled”: Driven output: no effect

Default value is “high_z”.

Getter

Return one of the above strings

Setter

Set the Target IO3 mode.

Raises

ValueError – if new value is not one of the above modes

GPIOSettings.tio4 scope.io.tio4

The function of the Target IO4 pin.

TIO4 can be used for the following functions:
  • “serial_tx”: UART output

  • “high_z” / None: High impedance input

  • “gpio_low” / False: Driven output: logic 0

  • “gpio_high” / True: Driven output: logic 1

  • “gpio_disabled”: Driven output: no effect

Default value is “high_z”. Typically, this pin is used as a trigger input.

Getter

Return one of the above strings

Setter

Set the Target IO4 mode

Raises

ValueError – if new value is not one of the above modes

GPIOSettings.pdid scope.io.pdid

The state of the PDID pin.

See pdic for more information.

GPIOSettings.pdic scope.io.pdic

The state of the PDIC pin output pin.

This is a GPIO pin. The following values are allowed:
  • “high” / True: logic 1

  • “low” / False: logic 0

  • “disabled” / “default” / “high_z” / None: undriven

Getter

Return one of “high”, “low”, or “high_z”

Setter

Set the pin’s state

Raises: ValueError: if new state not listed above

GPIOSettings.nrst scope.io.nrst

The state of the NRST pin.

See pdic for more information.

GPIOSettings.glitch_hp scope.io.glitch_hp

Whether the high-power crowbar MOSFET is enabled.

The glitch output is an SMA-connected output line that is normally connected to a target’s power rails. If this setting is enabled, a high-powered MOSFET shorts the power-rail to ground when the glitch module’s output is active.

Warning

Use with caution - ensure that the glitch module is properly configured before enabling this setting, as it is possible to permanently damage hardware with this output.

Getter

Return True if enabled or False if disabled

Setter

Turn the high-power MOSFET on or off

GPIOSettings.glitch_lp scope.io.glitch_lp

Whether the low-power crowbar MOSFET is enabled.

This is the low-power version of glitch_hp - see that documentation for more details.

Warning

Use with caution - ensure that the glitch module is properly configured before enabling this setting, as it is possible to permanently damage hardware with this output.

GPIOSettings.extclk_src scope.io.extclk_src

The clock signal being used as input for EXTCLK.

Currently, this can only be HS1, which is the clock from the target. As such, this value is read-only.

GPIOSettings.hs2 scope.io.hs2

The clock signal routed to the HS2 high speed output pin.

Allowed clock signals are:
  • “clkgen”: The output from the CLKGEN module

  • “glitch”: The output from the glitch module

  • “disabled” / None: No clock; output driven low

Getter

Return one of “clkgen”, “glitch”, or “disabled”

Setter

Set the clock to be output on HS2.

Raises: ValueError: if new value not listed above

GPIOSettings.target_pwr scope.io.target_pwr

Whether the target board is powered by the ChipWhisperer.

If True, the ChipWhisperer is currently supplying power to the target board; if False, it is not. This setting can be used to cycle power to the target or to help program it.

If the target board is powered through an external supply, this setting may have no effect.

Getter

Return the current power state of the target (True or False)

Setter

Turn the target power on or off.

GPIOSettings.tio_states scope.io.tio_states

Reads the logic level of the TIO pins (1-4) and returns them as a tuple of the logic levels.

Warning

ChipWhisperer firmware before release 5.2.1 does not support reading the TIO pins!

Getter

Read TIO states

Returns

A tuple of 1’s and 0’s representing the logic levels of each TIO pin

New in version 5.3: Add documented interface for the old method of reading TIO pins

GPIOSettings.cdc_settings scope.io.cdc_settings

Check or set whether USART settings can be changed via the USB CDC connection

i.e. whether you can change USART settings (baud rate, 8n1) via a serial client like PuTTY

Getter

An array of length four for four possible CDC serial ports (though only one is used)

Setter

Can set either via an integer (which sets both ports) or an array of length 4 (which sets each port)

Returns None if using firmware before the CDC port was added

trigger scope.trigger
TriggerSettings.triggers scope.trigger.triggers

The logical input into the trigger module.

The trigger module uses some combination of the scope’s I/O pins to produce a single value, which it uses for edge/level detection or UART triggers. This trigger output can combine 5 pins using one of 3 different boolean operations.

Pins:
  • tio1-4: Target I/O pins 1-4. Note that these pins can be in any mode.

  • nRST: Target I/O pin nRST. Note that these pins can be in any mode.

  • sma: An auxiliary SMA input, if available (only on CW1200)

Boolean operations:
  • OR: True if any inputs are True; False if none are

  • AND: True if all inputs are True; False if any are not

  • NAND: False if all inputs are True; True if any are not

Note that only one boolean operation can be used over all input pins.

Examples of acceptable trigger inputs:
  • “tio1”

  • “tio3 OR tio4”

  • “tio1 NAND tio2 NAND sma”

  • “nrst”

Examples of unallowed trigger inputs:
  • “tio1 tio2”

  • “tio1 AND tio2 OR tio3”

  • “tio1 OR tio1”

  • “tio1 XOR tio2”

  • “serial-tx”

Getter

Return a string describing the trigger mode (see examples)

Setter

Set the trigger mode using a string like the ones above

Raises

ValueError – if string cannot be converted to a legal mode

ProTrigger.module scope.trigger.module

The trigger module in use.

The trigger modules available depend on the hardware. On the CWLite, only the basic trigger module can be used; on the CW1200, the serial data and SAD triggers are available too.

Available trigger modules:
  • ‘basic’: Trigger on a logic level or edge

  • ‘SAD’: Trigger from SAD module (CWPro only)

  • ‘DECODEIO’: Trigger from decode_IO module (CWPro only)

Getter

Return the active trigger module

Setter

Sets the active trigger module

Raises

ValueError – module isn’t one of the available strings

ProTrigger.aux_out scope.trigger.module

Controls AUX out on the CWPro

CWPro only

Getter

Returns True if yes, False if no

Setter

Set True to enable aux_out, False to disable

glitch
Annotation

scope.glitch

GlitchSettings.clk_src scope.glitch.clk_src

The clock signal that the glitch DCM is using as input.

This DCM can be clocked from three different sources:
  • “target”: The HS1 clock from the target device

  • “clkgen”: The CLKGEN DCM output (not recommended for Husky)

  • “pll”: Husky’s on-board PLL clock (Husky only)

Getter

Return the clock signal currently in use

Setter

Change the glitch clock source

Raises

ValueError – New value not one of “target”, “clkgen” or “pll”

GlitchSettings.width scope.glitch.width

The width of a single glitch pulse

For CW-Husky, width is expressed as the number of phase shift steps.

For other capture hardware, width is expressed as a percentage of one period.

One pulse can range from -49.8% to roughly 49.8% of a period. The system may not be reliable at 0%. Note that negative widths are allowed; these act as if they are positive widths on the other half of the clock cycle.

Getter

Return a float with the current glitch width.

Setter

Update the glitch pulse width. The value will be adjusted to the closest possible glitch width.

Raises

UserWarning – Width outside of [-49.8, 49.8]. The value is rounded to one of these

GlitchSettings.width_fine scope.glitch.width_fine

The fine adjustment value on the glitch width.

This is a dimensionless number that makes small adjustments to the glitch pulses’ width. Valid range is [-255, 255]. N/A for Husky.

Warning

This value is write-only. Reads will always return 0.

Getter

Returns 0

Setter

Update the glitch fine width

Raises
  • TypeError – offset not an integer

  • ValueError – offset is outside of [-255, 255]

GlitchSettings.offset scope.glitch.offset

The offset from a rising clock edge to a glitch pulse rising edge, as a percentage of one period.

A pulse may begin anywhere from -49.8% to 49.8% away from a rising edge, allowing glitches to be swept over the entire clock cycle.

N/A for Husky.

Warning

very large negative offset <-45 may result in double glitches

Getter

Return a float with the current glitch offset.

Setter

Set the glitch offset. The new value is rounded to the nearest possible offset.

Raises
  • TypeError – offset not an integer

  • UserWarning – value outside range [-50, 50] (value is rounded)

GlitchSettings.offset_fine scope.glitch.offset_fine

The fine adjustment value on the glitch offset.

This is a dimensionless number that makes small adjustments to the glitch pulses’ offset. Valid range is [-255, 255].

Warning

This value is write-only. Reads will always return 0.

Getter

Returns 0

Setter

Update the glitch fine offset

Raises
  • TypeError – if offset not an integer

  • ValueError – if offset is outside of [-255, 255]

GlitchSettings.trigger_src scope.glitch.trigger_src

The trigger signal for the glitch pulses.

The glitch module can use four different types of triggers:
  • “continuous”: Constantly trigger glitches

  • “manual”: Only trigger glitches through API calls

  • “ext_single”: Use the trigger module. One glitch per scope arm.

  • “ext_continuous”: Use the trigger module. Many glitches per arm.

Warning

calling scope.arm() in manual gitch mode will cause a glitch to trigger.

Getter

Return the current trigger source.

Setter

Change the trigger source.

Raises

ValueError – value not listed above.

GlitchSettings.manual_trigger scope.glitch.manual_trigger
GlitchSettings.arm_timing scope.glitch.arm_timing

When to arm the glitch in single-shot mode.

If the glitch module is in “ext_single” trigger mode, it must be armed when the scope is armed. There are two timings for this event:

  • “no_glitch”: The glitch module is not armed. Gives a moderate speedup to capture.

  • “before_scope”: The glitch module is armed first.

  • “after_scope”: The scope is armed first. This is the default.

This setting may be helpful if trigger events are happening very early.

If the glitch module is not in external trigger single-shot mode, this setting has no effect.

Getter

Return the current arm timing (“before_scope” or “after_scope”)

Setter

Change the arm timing

Raises

ValueError – if value not listed above

GlitchSettings.ext_offset scope.glitch.ext_offset

How long the glitch module waits between a trigger and a glitch.

After the glitch module is triggered, it waits for a number of clock cycles before generating glitch pulses. This delay allows the glitch to be inserted at a precise moment during the target’s execution to glitch specific instructions.

Has no effect when trigger_src = ‘manual’ or ‘continuous’.

Note

It is possible to get more precise offsets by clocking the glitch module faster than the target board.

This offset must be in the range [0, 2**32).

Getter

Return the current external trigger offset.

Setter

Set the external trigger offset.

Raises
  • TypeError – if offset not an integer

  • ValueError – if offset outside of range [0, 2**32)

GlitchSettings.repeat scope.glitch.repeat

The number of glitch pulses to generate per trigger.

When the glitch module is triggered, it produces a number of pulses that can be combined with the clock signal. This setting allows for the glitch module to produce stronger glitches (especially during voltage glitching).

Repeat counter must be in the range [1, 8192].

Getter

Return the current repeat value (integer)

Setter

Set the repeat counter

Raises
  • TypeError – if value not an integer

  • ValueError – if value outside [1, 8192]

GlitchSettings.output scope.glitch.output

The type of output produced by the glitch module.

There are 5 ways that the glitch module can combine the clock with its glitch pulses:

  • “clock_only”: Output only the original input clock.

  • “glitch_only”: Output only the glitch pulses - do not use the clock.

  • “clock_or”: Output is high if either the clock or glitch are high.

  • “clock_xor”: Output is high if clock and glitch are different.

  • “enable_only”: Output is high for glitch.repeat cycles.

Some of these settings are only useful in certain scenarios:
  • Clock glitching: “clock_or” or “clock_xor”

  • Voltage glitching: “glitch_only” or “enable_only”

Getter

Return the current glitch output mode (one of above strings)

Setter

Change the glitch output mode.

Raises

ValueError – if value not in above strings

SAD scope.SAD - CW1200 Pro Only

Communicates with and drives the Sum of Absolute Differences module on the ChipWhisperer Pro.

Example for triggering off of some previously collected scope data:

scope.SAD.reference = trace.wave[1000:1000+128]
scope.SAD.threshold = 5000
scope.SAD.start()
scope.trigger.module = "SAD"
scope.adc.basic_mode = "rising_edge"

#can now capture as normal
trace = cw.capture_trace(scope, target, text, key)
ChipWhispererSAD.threshold scope.SAD.threshold

The threshold for the SAD trigger.

The threshold has a maximum value of 100 000. You should set the reference waveform via SAD.reference before setting this value.

Getter

Return the current threshold

Setter

Set the current threshold

Raises
  • ValueError – The user attempted to set a threshold above 100 000

  • IOError – User attempted to set the threshold before the reference waveform.

ChipWhispererSAD.reference scope.SAD.reference

Set the reference data for the SAD Trigger.

The reference must be 128 samples long. Through this interface, it is represented as a numpy array of floats between -0.5 and 0.5 (the same as trace data).

Getter

Gets the currently set SAD reference

Setter

Sets the SAD reference

Raises

ValueError – Data not 128 samples long

SAD.start()

Starts the SAD module. Must be done each time after changing the reference waveform.

DecodeIO scope.DecodeIO - CW1200 Pro Only

Communicates with and drives the Digital Pattern Match module on the ChipWhisperer Pro.

Basic usage for triggering on ‘r\n’:

# assuming setup scope
scope.trigger.triggers = 'tio1'
scope.trigger.module = 'DECODEIO'
scope.decode_IO.rx_baud = 38400
scope.decode_IO.decode_type = 'USART'
scope.decode_IO.trigger_pattern = ['r', '\n']
ChipWhispererDecodeTrigger.trigger_pattern scope.DecodeIO.trigger_pattern

The pattern to trigger off of.

Getter

Get the currently set trigger pattern

Setter

Sets the trigger pattern. Expects a list of ASCII characters/ints. ints in this list are equivalent to their corresponding ASCII representation. For example, [0x10] is the same as [’\n’].

Warns the user if they try to set an incorrect pattern.

Example to trigger off of ‘r\n’:

scope.decode_IO.trigger_pattern = ['r', 0x10]
ChipWhispererDecodeTrigger.rx_baud scope.DecodeIO.rx_baud

The baud rate of the serial data to trigger off of

The baud rate can be between 0 and 1E6

Getter

Gets the set baud rate

Setter

Sets the baud rate

Raises

ValueError – User attempted to set baud rate out of bounds

default_setup()

Sets up sane capture defaults for this scope

  • 25dB gain

  • 5000 capture samples

  • 0 sample offset

  • rising edge trigger

  • 7.37MHz clock output on hs2

  • 4*7.37MHz ADC clock

  • tio1 = serial rx

  • tio2 = serial tx

  • CDC settings change off

New in version 5.1: Added default setup for OpenADC

arm()

Setup scope to begin capture/glitching when triggered.

The scope must be armed before capture or glitching (when set to ‘ext_single’) can begin.

Raises
  • OSError – Scope isn’t connected.

  • Exception – Error when arming. This method catches these and disconnects before reraising them.

capture(poll_done=False)

Captures trace. Scope must be armed before capturing.

Parameters

poll_done (bool) – Supported by Husky only. Poll Husky to find out when it’s done capturing, instead of calculating the capture time based on the capture parameters. Can result in slightly faster captures when the number of samples is high. Defaults to False.

Return type

bool

Returns

True if capture timed out, false if it didn’t.

Raises

IOError – Unknown failure.

Changed in version 5.6.1: Added poll_done parameter for Husky

get_last_trace(as_int=False)

Return the last trace captured with this scope.

Can return traces as floating point values (as_int=False) or as integers.

Floating point values are scaled and shifted to be between -0.5 and 0.5.

Integer values are raw readings from the ChipWhisperer ADC. The ChipWhisperer-Lite has a 10-bit ADC, the Nano has an 8-bit ADC, and the Husky can read either 8-bits or 12-bits of ADC data.

Parameters

as_int (bool) – If False, return trace as a float. Otherwise, return as an int.

Return type

ndarray

Returns

Numpy array of the last capture trace.

Changed in version 5.6.1: Added as_int parameter

capture_segmented()

Captures trace in segment mode, returns as many segments as buffer holds.

Timeouts not handled yet properly (function will lock). Be sure you are generating enough triggers for segmented mode.

Returns

True if capture timed out, false if it didn’t.

Raises

IOError – Unknown failure.

New in version 5.5: Added segmented capture (requires custom bitstream)

get_last_trace_segmented()

Return last trace assuming it was captued with segmented mode.

NOTE: The length of each returned trace is 1 less sample than requested.

Returns

2-D numpy array of the last captured traces.

New in version 5.5: Added segmented capture (requires custom bitstream)

reload_fpga(bitstream=None, reconnect=True, prog_speed=1000000.0)

(Re)loads a FPGA bitstream (even if already configured).

Will cause a reconnect event, all settings become default again. If no bitstream specified default is used based on current configuration settings.

get_serial_ports()

Get serial ports associated with a ChipWhisperer

New in version 5.5: Add get_serial_ports()

Return type

Optional[List[Dict[str, int]]]

dis()

Disconnects the current scope object.

Returns

True if the disconnection was successful, False otherwise.

con(sn=None, idProduct=None, bitstream=None, force=False, prog_speed=10000000.0, **kwargs)

Connects to attached chipwhisperer hardware (Lite, Pro, or Husky)

Parameters
  • sn (str) – The serial number of the attached device. Does not need to be specified unless there are multiple devices attached.

  • idProduct (int) – The product ID of the ChipWhisperer. If None, autodetects product ID. Optional.

  • bitstream (str) – Path to bitstream to program. If None, programs default bitstream. Optional.

  • force (bool) – Force reprogramming of bitstream. If False, only program bitstream if no bitstream is currently programmed. Optional.

Returns

True if connection is successful, False otherwise

Changed in version 5.5: Added idProduct, bitstream, and force parameters.

upgrade_firmware()

Attempt a firmware upgrade. See https://chipwhisperer.readthedocs.io/en/latest/firmware.html for more information.

New in version 5.6.1: Improved programming interface

sn

The USB serial number of this scope.

Can be passed to cw.scope() to specify which ChipWhisperer to connect to

Return type

str

latest_fw

Get the newest firmware as a dict with elements major, minor and debug

Return type

Dict[str, int]

fw_version

Get current firmware version as a dict with elements major, minor and debug

Return type

Dict[str, int]

fw_version_str

A string of the firmware version:

'x.y.z'
Return type

str

sam_build_date

The date the SAM3U firmware was built on

New in version 5.6.1: Added sam build date to chipwhisperer

Return type

str

ChipWhisperer_Husky

ChipWhisperer Nano Scope

class CWNano

CWNano scope object.

This class contains the public API for the CWNano hardware. It includes specific settings for each of these devices.

To connect to one of these devices, the easiest method is:

import chipwhisperer as cw
scope = cw.scope(type=scopes.CWNano)

Some sane default settings can be set using:

scope.default_setup()

For more help about scope settings, try help() on each of the ChipWhisperer scope submodules (scope.adc, scope.io, scope.glitch):

adc scope.adc
ADCSettings.samples scope.adc.samples

Number of samples to store.

ADCSettings.clk_src scope.adc.clk_src

ADC Clock source.

Getter

Returns ‘int’ or ‘ext’ based on the clock source.

Setter

(str) Set the ADC clock source to either internal or external: (‘int’ or ‘ext’)

ADCSettings.clk_freq scope.adc.clk_freq

Set the frequency for CLKOUT. Will be rounded to nearest possible values, check results to see programmed value. Set to ‘None’ for disabling (High-Z) output.

Getter

Returns the actual frequency for CLKOUT

Setter

Sets CLKOUT to the nearest possible value.

io scope.io
GPIOSettings.tio1 scope.io.tio1

The function of the Target IO1 pin.

TIO1 can be used for the following functions:
  • “serial_rx”: UART input

Default value is “serial_rx”.

Getter

Return None

Setter

Set the Target IO1 mode. Raises: ValueError if new value is not one of the above modes

GPIOSettings.tio2 scope.io.tio2

The function of the Target IO2 pin.

TIO2 can be used for the following functions:
  • “serial_tx”: UART output

Default value is “serial_tx”.

Getter

Return None

Setter

Set the Target IO2 mode. Raises: ValueError if new value is not one of the above modes

GPIOSettings.tio3 scope.io.tio3

The function of the Target IO3 pin.

TIO3 can be used for the following functions:
  • “high_z” / None: High impedance input

  • “gpio_low” / False: Driven output: logic 0

  • “gpio_high” / True: Driven output: logic 1

  • “gpio_disabled”: Driven output: no effect

Default value is “high_z”.

Getter

Return one of the above strings

Setter

Set the Target IO3 mode. Raises: ValueError if new value is not one of the above modes

GPIOSettings.tio4 scope.io.tio4

The function of the Target IO4 pin.

TIO4 can be used for the following functions:
  • “high_z” / None: High impedance input

Default value is “high_z”. Typically, this pin is used as a trigger input.

Getter

Return None

Setter

Set the Target IO4 mode Raises: ValueError if new value is not one of the above modes

GPIOSettings.pdid scope.io.pdid

The state of the PDID pin.

See pdic for more information.

GPIOSettings.pdic scope.io.pdic

The state of the PDIC pin output pin.

This is a GPIO pin. The following values are allowed:
  • “high” / True: logic 1

  • “low” / False: logic 0

  • “disabled” / “default” / “high_z” / None: undriven

Getter

Return one of “high”, “low”, or “high_z”

Setter

Set the pin’s state Raises: ValueError if new state not listed above

GPIOSettings.nrst scope.io.nrst

The state of the NRST pin.

See pdic for more information.

GPIOSettings.clkout scope.io.clkout

“Set the frequency for CLKOUT. Will be rounded to nearest possible values, check results to see programmed value. Set to ‘None’ for disabling (High-Z) output.

GPIOSettings.cdc_settings scope.io.cdc_settings

Check or set whether USART settings can be changed via the USB CDC connection

i.e. whether you can change USART settings (baud rate, 8n1) via a serial client like PuTTY

Getter

An array of length two for two possible CDC serial ports (though only one is used)

Setter

Can set either via an integer (which sets both ports) or an array of length 2 (which sets each port)

Returns None if using firmware before the CDC port was added

glitch scope.glitch
GlitchSettings.ext_offset scope.glitch.ext_offset

Offset from rising edge of trigger & when glitch gets inserted, approx = 8.3 ns * ext_offset

GlitchSettings.repeat scope.glitch.repeat

Width of glitch in cycles (approx = 8.3 ns * width)

default_setup()

Sets up sane capture defaults for this scope

  • 7.5MHz ADC clock

  • 7.5MHz output clock

  • 5000 capture samples

  • tio1 = serial rx

  • tio2 = serial tx

  • glitch module off

New in version 5.1: Added default setup for CWNano

arm()

Arm the ADC, the trigger will be GPIO4 rising edge (fixed trigger).

capture(poll_done=False)

Raises IOError if unknown failure, returns ‘True’ if timeout, ‘False’ if no timeout

get_last_trace(as_int=False)

Return the last trace captured with this scope.

Can return traces as floating point values (as_int=False) or as integers.

Floating point values are scaled and shifted to be between -0.5 and 0.5.

Integer values are raw readings from the ChipWhisperer ADC. The ChipWhisperer-Lite has a 10-bit ADC, the Nano has an 8-bit ADC, and the Husky can read either 8-bits or 12-bits of ADC data.

Parameters

as_int (bool) – If False, return trace as a float. Otherwise, return as an int.

Returns

Numpy array of the last capture trace.

Changed in version 5.6.1: Added as_int parameter

get_serial_ports()

Get serial ports associated with a ChipWhisperer

New in version 5.5: Add get_serial_ports()

Return type

Optional[List[Dict[str, int]]]

con(sn=None, **kwargs)

Connects to attached chipwhisperer hardware (Nano)

Parameters

sn (str) – The serial number of the attached device. Does not need to be specified unless there are multiple devices attached.

Returns

True if connection is successful, False otherwise.

dis()

Disconnects the current scope object.

Returns

True if the disconnection was successful, False otherwise.

upgrade_firmware()

Attempt a firmware upgrade. See https://chipwhisperer.readthedocs.io/en/latest/firmware.html for more information.

New in version 5.6.1: Improved programming interface

sn

The USB serial number of this scope.

Can be passed to cw.scope() to specify which ChipWhisperer to connect to

Return type

str

latest_fw

Get the newest firmware as a dict with elements major, minor and debug

Return type

Dict[str, int]

fw_version

Get current firmware version as a dict with elements major, minor and debug

Return type

Dict[str, int]

fw_version_str

A string of the firmware version:

'x.y.z'
Return type

str

sam_build_date

The date the SAM3U firmware was built on

New in version 5.6.1: Added sam build date to chipwhisperer

Return type

str

Firmware Update

On some occasions it is necessary to reprogram the scope of the ChipWhisperer Nano, Lite or Pro. The easist way to both enter the bootloader and flash new firmware is through our SAMFWLoader class.

See also

You can also use the BOSSA BOSSA utiltiy to reflash the SAM3U firmware. If you need to build it from source, NewAE keeps a slightly modified version of the source at https://github.com/newaetech/BOSSA

class SAMFWLoader(scope=None, logfunc=<built-in function print>)

Object for easy reprogramming of ChipWhisperers

See https://chipwhisperer.readthedocs.io/en/latest/firmware.html for information on how to update.

Can autoprogram if the ChipWhisperer’s firmware has not already been erased.

Autoprogram Example:

  1. Attach the scope part of the hardware to your computer.

  2. Connect to the scope using:

    import chipwhisperer as cw
    
    # Connect to scope
    scope = cw.scope()
    
    # If using CW305, connect to target as well
    # Can ignore msg about no bitstream
    target = cw.target(None, cw.targets.CW305)
    
  1. Call the auto_program() method:

    programmer = cw.SAMFWLoader(scope=scope)
    # if CW305
    # programmer = cw.SAMFWLoader(scope=target)
    
    programmer.auto_program()
    

Example

  1. Attach the scope part of the hardware to your computer.

  2. Connect to the scope using:

    import chipwhisperer as cw
    
    # Connect to scope
    scope = cw.scope()
    
    # If using CW305, connect to target as well
    # Can ignore msg about no bitstream
    target = cw.target(None, cw.targets.CW305)
    
  3. Place the hardware in bootloader mode using:

    # use created scope object from previous step
    programmer = cw.SAMFWLoader(scope=scope)
    
    # or CW305 target object
    programmer = cw.SAMFWLoader(scope=target)
    
    # WARNING: this will erase the firmware on the device
    # and make it unusable until reprogrammed.
    programmer.enter_bootloader(really_enter=True)
    
  4. Unplug then plug in the hardware into your computer again. The device should be shown as BOSSA in the device manager on Windows. Make not of the port number the BOSSA device is attached to (for example: COM1, or COM2, and so on)

  5. Program the SAM3U with:

    import chipwhisperer as cw
    programmer = cw.SAMFWLoader(scope=None)
    

    Two methods:

    1. Using the firmware_path:

      # the firmware file is included with chipwhisperer
      # and is the .bin file from the FW build
      # (ChipWhisperer Lite) chipwhisperer\hardware\capture\chipwhisperer-lite\sam3u_fw\SAM3U_VendorExample\Debug
      # directory.
      programmer.program(<port>, <path to firmware file>)
      
    2. Using the hardware_type (recommended):

      programmer.program(<port>, hardware_type='cwlite')
      programmer.program(<port>, hardware_type='cwnano')
      programmer.program(<port>, hardware_type='cw305')
      programmer.program(<port>, hardware_type='cw1200')
      

    On Linux instead of ‘COM#’ use the Linux equivalent (usually /dev/ttyACM# or /dev/ttyUSB#)

  6. Once the programming is done. Unplug then plug in the hardware into your computer again. The device should show up as a ChipWhisperer again.

enter_bootloader(really_enter=False)

Enters the bootloader of the ChipWhisperer by erasing the flash

Only use this if you want to erase the scope’s firmware (i.e. the ChipWhisperer Lite). This does NOT erase the firmware of a target ( i.e. an STM32 target). Will raise a Warning the first time an erase is attempted and really_enter=False.

Parameters

really_enter (bool, optional) – If True, enter the bootloader without ever raising a warning. If False, raise a warning if this is the user’s first time calling it.

Raises

Warning – really_enter=False and user hasn’t seen this warning before

program(port, fw_path=None, hardware_type=None, bypass_warning=False)

Program the ChipWhisperer with new firmware.

Parameters
  • port (str) – Serial port that the ChipWhisperer bootloader is on

  • fw_path (str) – Path to firmware, if specified leave out hardware type.

  • hardware_type (str) – The type of hardware that you want to program. If specified leave out fw_path. Valid types: (cwlite, cwnano, cw305, cw1200)

Returns

True if programming succeeded, False if it didn’t

auto_program()

Erase and program firmware of ChipWhisperer

Autodetects comport and hardware type.

Target

The target object provides the interface for configuring the target device under test (DUT). Supported targets:

The Simple Serial target type provides the target interface for all targets that use a simple serial connection. A object can be created using:

import chipwhisperer as cw
scope = cw.scope()
target = cw.target(scope)

You now have access to the target configuration using the target variable.

target(scope, target_type=<class 'chipwhisperer.capture.targets.SimpleSerial.SimpleSerial'>, **kwargs) chipwhisperer.target(scope, target_type=targets.SimpleSerial, **kwargs)

Create a target object and connect to it.

Parameters
  • scope (ScopeTemplate) – Scope object that we’re connecting to the target through.

  • target_type (TargetTemplate, optional) – Target type to connect to. Defaults to targets.SimpleSerial. Types can be found in chipwhisperer.targets.

  • **kwargs – Additional keyword arguments to pass to target setup. Rarely needed.

Return type

Union[CW305, CW305_ECC, CW310, SimpleSerial, SimpleSerial2, SimpleSerial2_CDC]

Returns

Connected target object specified by target_type.

Simple Serial Target

class SimpleSerial

SimpleSerial target object.

This class contains the public API for a target that uses serial communication.

The easiest way to connect to the target is:

import chipwhisperer as cw
scope = cw.scope()
target = cw.target(scope)

The target is automatically connected to if the default configuration adequate.

For more help use the help() function with one of the submodules (target.baud, target.write, target.read, …).

Warning

The CWLite, CW1200, and CWNano have a 128 byte read buffer and a 128 byte send buffer. If the read buffer overflows, a warning message will be printed. Prior to firmware 0.20, the send buffer can silently overflow. In ChipWhisperer 5.4, this is upgraded to a 200 byte read/send buffer.

write(data)

Writes data to the target over serial.

Parameters

data (str) – Data to write over serial.

Raises

Warning – Target not connected

New in version 5.1: Added target.write()

read(num_char=0, timeout=250)

Reads data from the target over serial.

Parameters
  • num_char (int, optional) – Number of byte to read. If 0, read all data available. Defaults to 0.

  • timeout (int, optional) – How long in ms to wait before returning. If 0, block for a long time. Defaults to 250.

Returns

String of received data.

New in version 5.1: Added target.read()

simpleserial_wait_ack(timeout=500)

Waits for an ack from the target for timeout ms

Parameters

timeout (int, optional) – Time to wait for an ack in ms. If 0, block until we get an ack. Defaults to 500.

Returns

The return code from the ChipWhisperer command or None if the target failed to ack

Raises

Warning – Target not connected.

New in version 5.1: Added target.simpleserial_wait_ack

New in version 5.2: Defined return value

simpleserial_write(cmd, num, end='\n')

Writes a simpleserial command to the target over serial.

Writes ‘cmd’ + ascii(num) + ‘end’ over serial. Flushes the read and write buffers before writing.

Parameters
  • cmd (str) – String to start the simpleserial command with. For ‘p’.

  • num (bytearray) – Number to write as part of command. For example, the 16 byte plaintext for the ‘p’ command. Converted to hex-ascii before being sent. If set to ‘none’ is omitted.

  • end (str, optional) – String to end the simpleserial command with. Defaults to ‘n’.

Example

Sending a ‘p’ command:

key, pt = ktp.new_pair()
target.simpleserial_write('p', pt)
Raises

Warning – Write attempted while disconnected or error during write.

New in version 5.1: Added target.simpleserial_write()

simpleserial_read(cmd, pay_len, end='\n', timeout=250, ack=True)

Reads a simpleserial command from the target over serial.

Reads a command starting with <start> with an ASCII encoded bytearray payload of length exp_len*2 (i.e. exp_len=16 for an AES128 key) and ending with <end>. Converts the payload to a bytearray. Will ignore non-ASCII bytes in the payload, but warn the user of them.

Parameters
  • cmd (str) – Expected start of the command. Will warn the user if the received command does not start with this string.

  • pay_len (int) – Expected length of the returned bytearray in number of bytes. Note that SimpleSerial commands send data as ASCII; this is the length of the data that was encoded.

  • end (str, optional) – Expected end of the command. Will warn the user if the received command does not end with this string. Defaults to ‘n’

  • timeout (int, optional) – Value to use for timeouts during reads in ms. If 0, block until all expected data is returned. Defaults to 250.

  • ack (bool, optional) – Expect an ack at the end for SimpleSerial >= 1.1. Defaults to True.

Returns

The received payload as a bytearray or None if the read failed.

Example

Reading ciphertext back from the target after a ‘p’ command:

ct = target.simpleserial_read('r', 16)
Raises

Warning – Device did not ack or error during read.

New in version 5.1: Added target.simpleserial_read()

simpleserial_read_witherrors(cmd, pay_len, end='\n', timeout=250, glitch_timeout=8000, ack=True)

Reads a simpleserial command from the target over serial, but returns invalid responses.

Reads a command starting with <start> with an ASCII encoded bytearray payload of length exp_len*2 (i.e. exp_len=16 for an AES128 key) and ending with <end>. Converts the payload to a bytearray, returns a dictionary showing if processing was successful along with decoded and raw values. This function is designed to be used with glitching where you may have invalid responses.

Parameters
  • cmd (str) – Expected start of the command. Will warn the user if the received command does not start with this string.

  • pay_len (int) – Expected length of the returned bytearray in number of bytes. Note that SimpleSerial commands send data as ASCII; this is the length of the data that was encoded.

  • end (str, optional) – Expected end of the command. Will warn the user if the received command does not end with this string. Defaults to ‘n’

  • timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.

  • glitch_timeout (int, optional) – Value to wait for additional data if expected data isn’t returned. Useful to have a longer timeout for a reset or other unexpected event.

  • ack (bool, optional) – Expect an ack at the end for SimpleSerial >= 1.1. Defaults to True.

Returns

valid (bool): Did response look valid? payload: Bytearray of decoded data (only if valid is ‘True’, otherwise None) full_response: Raw output of serial port. rv: If ‘ack’ in command, includes return value

Return type

A dictionary with these elements

Example

Reading the output of one of the glitch tests when no error:

resp = target.simpleserial_read_witherrors(‘r’, 4) print(resp) >{‘valid’: True, ‘payload’: CWbytearray(b’c4 09 00 00’), ‘full_response’: ‘rC4090000n’, ‘rv’: 0}

Reading the output of one of the glitch tests when an error happened:

resp = target.simpleserial_read_witherrors(‘r’, 4) print(resp) >{‘valid’: False, ‘payload’: None, ‘full_response’: ‘x00x00x00x00x00x00x00rRESET n’, ‘rv’: None}

Raises

Warning – Device did not ack or error during read.

New in version 5.2: Added target.simpleserial_read_witherrors()

set_key(key, ack=True, timeout=250)

Checks if key is different than the last one sent. If so, send it.

Uses simpleserial_write(‘k’)

Parameters
  • key (bytearray) – key to send

  • ack (bool, optional) – Wait for ack after sending key. Defaults to True.

  • timeout (int, optional) – How long in ms to wait for the ack. Defaults to 250.

Raises

Warning – Device did not ack or error during read.

New in version 5.1: Added target.set_key()

in_waiting()

Returns the number of characters available from the serial buffer.

Returns

The number of characters available via a target.read() call.

New in version 5.1: Added target.in_waiting()

in_waiting_tx()

Returns the number of characters waiting to be sent by the ChipWhisperer.

Requires firmware version >= 0.2 for the CWLite/Nano and firmware version and firmware version >= 1.2 for the CWPro.

Used internally to avoid overflowing the TX buffer, since CW version 5.3

Returns

The number of characters waiting to be sent to the target

New in version 5.3.1: Added public method for in_waiting_tx().

flush()

Removes all data from the serial buffer.

New in version 5.1: Added target.flush()

close()

Close target

con(scope=None, **kwargs)

Connect to target

get_simpleserial_commands(timeout=250, ack=True)

Gets available simpleserial commands for target

Parameters
  • timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.

  • ack (bool, optional) – Wait for ack after sending key. Defaults to True.

Returns

List of dics with fields ‘cmd’ command_byte, ‘len’ command_length, ‘flags’ command_flags

baud

The current baud rate of the serial connection.

Getter

Return the current baud rate.

Setter

Set a new baud rate. Valid baud rates are any integer in the range [500, 2000000].

Raises

AttributeError – Target doesn’t allow baud to be changed.

output_len

The length of the output expected from the crypto algorithm (in bytes)

simpleserial_last_sent

The last raw string written via simpleserial_write

simpleserial_last_read

The last raw string read by a simpleserial_read* command

Simple Serial V2 Target

class SimpleSerial2

Target object for new SimpleSerial V2 protocol.

New in version 5.4: Added SimpleSerial V2 (not on by default)

Currently, the easiest way to use it is:

scope = cw.scope()
target = cw.target(scope, cw.targets.SimpleSerial2, flush_on_err=False)

For more help, use the help() function with one of the submodules (target.baud, target.write, target.read, …).

The protocol is as follows:

[cmd, subcmd, data_len, data_0, …, data_n, crc (poly=0xA6)]

The frame is then consistant overhead byte stuffed (COBS) to remove all 0x00 bytes. An 0x00 byte is then appended to the end of the frame.

Uses 230400bps by default.

Return packets have the form:

[cmd, data_len, data_0, …, data_n, crc (poly=0xA6)]

All commands sent to the target will be responded to with an ack/error packet.

Allows us to send more information in the same number of bytes. Also should be more robust and a bit easier to work with:

  1. It’s easy to reset communications by sending frame bytes (0x00)

  2. We have many ways of checking the validity of a packet:

    -Frame byte where it shouldn’t be -No frame byte at end of message -CRC

  3. No need to specify length of return message

write(data)
read(num_char=0, timeout=250)

Reads data from the target over serial.

Parameters
  • num_char (int, optional) – Number of byte to read. If 0, read all data available. Defaults to 0.

  • timeout (int, optional) – How long in ms to wait before returning. If 0, block until data received. Defaults to 250.

Returns

String of received data.

send_cmd(cmd, scmd, data)

Send a SSV2 command to the target.

Does all the CRC/Byte stuffing for you

Parameters
  • cmd (char or int) – The command to use

  • scmd (int) – The subcommand to use

  • data (bytearray) – The data to send

read_cmd(cmd=None, pay_len=None, timeout=250, flush_on_err=None)

Read and decode simpleserial-v2 command

Parameters
  • cmd (str, optional) – Expected start of the command. Will warn the user if the received command does not start with this string. Defaults to None

  • pay_len (int, optional) – Expected length of the returned bytearray in number of bytes. If None, uses the length field of the packet to determine how much data to read

  • timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.

  • flush_on_err (bool/None, optional) – If True, reset/flush the serial lines. If False, don’t. If None, determine via whether or not flush_on_err was True or False when passed to con()

reset_comms()

Try to reset communication with the target and put it in a state to read commands

Sends 10 0x00 bytes, sleeps for 0.05 seconds, then flushes the serial buffer

simpleserial_wait_ack(timeout=500)

Waits for an ack/error packet from the target for timeout ms

Parameters

timeout (int, optional) – Time to wait for an ack in ms. If 0, block until we get an ack. Defaults to 500.

Returns

The return code from the ChipWhisperer command or None if the target failed to ack

simpleserial_write(cmd, data, end='\n')

Mimic SimpleSerial v1 behaviour with new firmware

Internal/firmware details may change

Special cases for ‘p’ and ‘k’ to use sub command to select what to do with simpleserial-aes

Parameters
  • cmd (str) – If ‘p’, SSV2 cmd=0x01, scmd=0x01. If ‘k’, SSV2 cmd=0x01, scmd=0x02. Otherwise, SSV2 cmd=cmd, scmd=0x00.

  • data (bytearray) – Number to write as part of command. For example, the 16 byte plaintext for the ‘p’ command. If an empty list is given, [0x00] is sent.

  • end (str, optional) – Unused

Example

Sending a ‘p’ command:

key, pt = ktp.new_pair()
target.simpleserial_write('p', pt)
simpleserial_read(cmd=None, pay_len=None, end='\n', timeout=250, ack=True)

Reads back response from target and ack packet.

Parameters
  • cmd (str, optional) – Expected start of the command. Will warn the user if the received command does not start with this string. Defaults to None

  • pay_len (int, optional) – Expected length of the returned bytearray in number of bytes. If None, uses the length field of the packet to determine how much data to read

  • end (str, optional) – Unused

  • timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.

  • ack (bool, optional) – Expect an ack packet at the end for SimpleSerial 2. Defaults to True.

simpleserial_read_witherrors(cmd=None, pay_len=None, end='\n', timeout=250, glitch_timeout=1000, ack=True)

Reads a simpleserial command from the target over serial, but returns invalid responses.

Reads a command starting with <start> with a COBS encoded bytearray payload of length pay_len (i.e. pay_len=16 for an AES128 key) and ending with 0x00. Does normal read_cmd() stuff (decoding, etc). If an error is found (timeout, frame issues, etc), a single read of 1000 character with glitch_timeout as a timeout is done, and the raw response is returned.

The packet will be valid if:

  • All requested reads return the requested characters

  • No frame bytes except the terminator are read

  • The packet doesn’t end with a frame byte

  • If an ack packet isn’t received

Parameters
  • cmd (str, optional) – Expected start of the command. Will warn the user if the received command does not start with this string. Defaults to None

  • pay_len (int, optional) – Expected length of the returned bytearray in number of bytes. If None, uses the length field of the packet to determine how much data to read

  • end (str, optional) – Unused

  • timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.

  • glitch_timeout (int, optional) – Value to wait for additional data if expected data isn’t returned. Useful to have a longer timeout for a reset or other unexpected event. Defaults to 1000

  • ack (bool, optional) – Expect an ack packet at the end for SimpleSerial >= 2. Defaults to True.

Returns

valid (bool): Did response look valid? payload: Bytearray of decoded data (only if valid is ‘True’, otherwise None) full_response: Raw output of serial port. rv: If ‘ack’ in command, includes return value

Return type

A dictionary with these elements

Example

Reading the output of one of the glitch tests when no error:

resp = target.simpleserial_read_witherrors(‘r’, 4) print(resp) >{‘valid’: True, ‘payload’: CWbytearray(b’c4 09 00 00’), ‘full_response’: ‘rC4090000n’, ‘rv’: 0}

Reading the output of one of the glitch tests when an error happened:

resp = target.simpleserial_read_witherrors(‘r’, 4) print(resp) >{‘valid’: False, ‘payload’: None, ‘full_response’: ‘x00x00x00x00x00x00x00rRESET n’, ‘rv’: None}

Raises

Warning – Device did not ack or error during read.

set_key(key, ack=True, timeout=250)

Checks if key is different than the last one sent. If so, send it.

Uses simpleserial_write(‘k’)

Parameters
  • key (bytearray) – key to send

  • ack (bool, optional) – Wait for ack after sending key. Defaults to True.

  • timeout (int, optional) – How long in ms to wait for the ack. Defaults to 250.

Raises

Warning – Device did not ack or error during read.

in_waiting()

Returns the number of characters available from the serial buffer.

Returns

The number of characters available via a target.read() call.

in_waiting_tx()

Returns the number of characters waiting to be sent by the ChipWhisperer.

Requires firmware version >= 0.2 for the CWLite/Nano and firmware version and firmware version >= 1.2 for the CWPro.

Used internally to avoid overflowing the TX buffer, since CW version 5.3

Returns

The number of characters waiting to be sent to the target

flush()

Removes all data from the serial buffer.

close()

Close target

con(scope=None, flush_on_err=True)

Connect to target

get_simpleserial_commands(timeout=250, flush_on_err=None, ack=True)

Gets available simpleserial commands for target

Parameters
  • timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.

  • flush_on_err (bool/None, optional) – If True, reset/flush the serial lines. If False, don’t. If None, determine via whether or not flush_on_err was True or False when passed to con()

  • ack (bool, optional) – Wait for ack after sending key. Defaults to True.

Returns

List of dics with fields ‘cmd’ command_byte, ‘len’ 0x00, ‘flags’ 0x00

baud

The current baud rate of the serial connection.

Getter

Return the current baud rate.

Setter

Set a new baud rate. Valid baud rates are any integer in the range [500, 2000000].

Raises

AttributeError – Target doesn’t allow baud to be changed.

Simple Serial V2 CDC Target

class SimpleSerial2_CDC

Target Option for Using SSV2 with a CDC Port

New in version 5.5: Added CDC SSV2

Currently, the easiest way to use it is:

scope = cw.scope()
target = cw.target(scope, cw.targets.SimpleSerial2_CDC)

Upon connection, this target object will using USB info from the scope object to figure out which serial port to use. You can also specify the serial port manually using the dev_path parameter.

target = cw.target(scope, cw.targets.SimpleSerial2_CDC, dev_path='COM5')

Other than that, usage is mostly the same as regular simpleserial V2, except the read timeout is always fixed to 250ms.

It does offer better performance than the regular SSV2 object if reading serial data back from the target.

CW305 FPGA Target

class CW305

CW305 target object.

This class contains the public API for the CW305 hardware. To connect to the CW305, the easiest method is:

import chipwhisperer as cw
scope = cw.scope()

# scope can also be None here, unlike with the default SimpleSerial
target = cw.target(scope,
        targets.CW305, bsfile=<valid FPGA bitstream file>)

As of CW5.3, you can also specify the following:

# can also be '35t'
target = cw.target(scope, fpga_id='100t')

To automatically program with the example AES bitstream

If you’re using the reference designs, typical configuration requires you to set the FPGA VCC-INT voltage and enable and set the clock via the PLL. You’ll probably also want to disable the USB clock during encryption to reduce noise:

target.vccint_set(1.0) #set VCC-INT to 1V

target.pll.pll_enable_set(True) #Enable PLL chip
target.pll.pll_outenable_set(False, 0) # Disable unused PLL0
target.pll.pll_outenable_set(True, 1)  # Enable PLL
target.pll.pll_outenable_set(False, 2) # Disable unused PLL2

# optional, but reduces power trace noise
target.clkusbautooff = True
target.clksleeptime = 1 # 1ms typically good for sleep

Don’t forget to clock the ChipWhisperer ADC off the FPGA instead of the internal clock:

scope.clock.adc_src = "extclk_x4"
scope.clock.reset_adc() # make sure the DCM is locked

Note that connecting to the CW305 includes programming the CW305 FPGA, if it isn’t already.

For more help about CW305 settings, try help() on this CW305 submodule:

  • target.pll

simpleserial_read(cmd, pay_len, end='\n', timeout=250, ack=True)

Read data from target

Mimics simpleserial protocol of serial based targets

Parameters
  • cmd (str) – Command to ues. Only accepts ‘r’ for now.

  • pay_len – Unused

  • end – Unused

  • timeout – Unused

  • ack – Unused

Returns: Value from Crypto output register

New in version 5.1: Added simpleserial_read to CW305

simpleserial_write(cmd, data, end=None)

Write data to target.

Mimics simpleserial protocol of serial based targets.

Parameters
  • cmd (str) – Command to use. Target supports ‘p’ (write plaintext), and ‘k’ (write key).

  • data (bytearray) – Data to write to target

  • end – Unused

Raises

ValueError – Unknown command

New in version 5.1: Added simpleserial_write to CW305

spi_mode(enable=True, timeout=200, bsfile=None, prog_speed=10000000.0)

Enter programming mode for the onboard SPI chip

Reprograms the FPGA with the appropriate bitstream and returns an object with which to program the CW305 SPI chip (see documentation on the returned object for more info)

Parameters
  • enable (bool) – Enable the SPI interface before returning it. Defaults to True

  • timeout (int) – USB timeout in ms. Defaults to 200.

  • bsfile (string) – If not None, program with a bitstream pointed to by bsfile. If None, program with SPI passthrough bitstream for the chip specified during connection (or cw.target())

Returns

A FPGASPI object which can be used to erase/program/verify/read the SPI chip on the CW305.

_con(scope=None, bsfile=None, force=False, fpga_id=None, defines_files=None, slurp=True, prog_speed=10000000.0)

Connect to CW305 board, and download bitstream.

If the target has already been programmed it skips reprogramming unless forced.

Parameters
  • scope (ScopeTemplate) – An instance of a scope object.

  • bsfile (path) – The path to the bitstream file to program the FPGA with.

  • force (bool) – Whether or not to force reprogramming.

  • fpga_id (string) – ‘100t’, ‘35t’, or None. If bsfile is None and fpga_id specified, program with AES firmware for fpga_id

  • defines_files (list, optional) – path to cw305_defines.v

  • slurp (bool, optional) – Whether or not to slurp the Verilog defines.

fpga_write(addr, data)

Write to an address on the FPGA

Parameters
  • addr (int) – Address to write to

  • data (list) – Data to write to addr

fpga_read(addr, readlen)

Read from an address on the FPGA

Parameters
  • addr (int) – Address to read from

  • readlen (int) – Length of data to read

Returns

Requested data as a list

clksleeptime

Time (in milliseconds) that the USB clock is disabled for upon capture, if self.clkusbautooff is set.

clkusbautooff

If set, the USB clock is automatically disabled on capture.

The USB clock is re-enabled after self.clksleeptime milliseconds.

Reads/Writes to the FPGA will not be possible until after the USB clock is reenabled, meaning usb_trigger_toggle() must be used to trigger the FPGA to perform an encryption.

Getter

Gets whether to turn off the USB clock on capture

Setter

Sets whether to turn off the USB clock on capture

pll target.pll
PLLCDCE906.pll_outenable_set target.pll.pll_outenable_set
PLLCDCE906.pll_outenable_get target.pll.pll_outenable_get
PLLCDCE906.pll_outfreq_set target.pll.pll_outfreq_set
PLLCDCE906.pll_outfreq_get target.pll.pll_outfreq_get
PLLCDCE906.pll_outsource_set target.pll.pll_outsource_set
PLLCDCE906.pll_outsource_get target.pll.pll_outsource_get
PLLCDCE906.pll_writedefaults target.pll.pll_writedefaults
PLLCDCE906.pll_outslew_set target.pll.pll_outslew_set
PLLCDCE906.pll_outslew_get target.pll.pll_outslew_get

CW305 SPI Program

class FPGASPI(usb, timeout=200)

Programmer for the CW305’s onboard SPI flash

Built for AT25DF321A, but has customizable codes for write enable/disable, chip erase, status, write, read, and block erase, as well as page size.

To program the SPI, the CW305 must be loaded with a special bitstream (will be done automatically if you specify fpga_id when connecting to the CW305) and have FW version > 0.30 for its USB microcontroller.

Basic usage:

fpga = cw.target(None, cw.targets.CW305, fpga_id='100t') #for CW305_100t
fpga = cw.target(None, cw.targets.CW305, fpga_id='35t') #for CW305_35t
spi = fpga.spi_mode()

spi.erase_chip() # can also use spi.erase_block() for smaller/faster erases
with open('bitfile.bit', 'rb') as f:
    data = list(f.read())
    spi.program(data) # also verifies by default

Warning

The AT25DF321A has the following behaviour:

  • Writes longer than a page (256 bytes) will use only the last 256 bytes

  • Reads can cross page boundaries (though read() and verify() will only read 256 bytes at a time)

  • Writes that don’t begin on a page bound will wrap if a page boundary is crossed

The user is responsible for ensuring that their writes begin on page boundaries.

erase_chip(timeout=None)

Erase the whole SPI chip. Slow (~25s)

Parameters

timeout (int) – Timeout in ms. If None, set to 0xFFFFFFFF (approx 1000 hours)

Raises

IOError – Erase timed out

erase_block(addr, size='4K', timeout=1000)

Erase a block on the SPI chip. See spi.ERASE_BLOCK for available erase lengths

Parameters
  • addr (int) – Address to erase from

  • size (string) – See spi.ERASE_BLOCK for available sizes

  • timeout (int) – Timeout in ms. If None, set to 0xFFFFFFFF (approx 1000 hours) Defaults to 1000 (1s).

Raises

IOError – Erase timed out

program(data, addr=0, verify=True, timeout=1000)

Program (and optionally verify) the chip with data.

Parameters
  • data (list) – data to write

  • addr (int) – Address to start programming from. Defaults to 0x00. Must align with a page.

  • verify (bool) – If True, verify data written at end of full write. Defaults to True.

  • timeout (int) – Timeout in ms for writes. If None, set to 0xFFFFFFFF (approx 1000 hours) Defaults to 1000 (1s).

Raises

IOError – Verify failed or timeout

verify(data, addr=0)

Verify the data on the SPI chip

Parameters
  • data (list) – data to verify

  • addr (int) – Address to start verification from. Defaults to 0x00. Must align with a page.

Raises

IOError – Verify failed

read(length, addr=0)

Read data on the SPI chip

Parameters
  • length (int) – Length of data to read

  • addr (int) – Address to start read from. Must align with a page.

CW305 SAM3U IO Control

class FPGAIO(usb, timeout=200)

User IO to override external bus.

Allows you to use any pin on the SAM3U as a user IO. This includes pins such as the external IO interface, and basically anything else you can find.

The pin names are strings, and come from one of three sources:
  • SAM3U pin names, such as “PC11”, “PB9”, etc.

  • Net names from the CW305 schematic such as “USB_A20”.

  • The FPGA ball location that is connected to the SAM3U pin, such as “M2”.

Any function taking a pin name assumes you pass a string with one of those. You do not need to specify your source - it will autodetect the pin name (if possible). The SAM3U pin names allow access to every pin, including those which are not actually connected on the PCB itself.

Beyond simple GPIO toggling, a bit-banged SPI interface can be defined and connected to any of the SAM3U pins. The bit-banged interface is done on the SAM3U microcontroller, with a default SCK frequency of around 1.5 MHz. You can additionally define waitstates to slow down this clock.

Basic usage:

fpga = cw.target(None, cw.targets.CW305)
io = target.gpio_mode()

# Take over the SAM3U blue LED (normally controlled by firmware, won't be after this)
import time
io.pin_set_output("LED_BLUE")
io.pin_set_state("LED_BLUE", 0)
time.sleep(0.5)
io.pin_set_state("LED_BLUE", 1)

# Example - toggle pin associated with FPGA pin C1 (would be USB_A11)
import time
io.pin_set_output("C1")
io.pin_set_state("C1", 0)
time.sleep(0.1)
io.pin_set_state("C1", 1)

# Setup a SPI interface based on schematic net names
io.spi1_setpins(sdo="USB_A20", sdi="USB_A19", sck="USB_A18", cs="USB_A17")
io.spi1_enable(True)

somedata = [0x11, 0x22, 0x33]

response = io.spi1_transfer(somedata)
print(response)
If you want to see all possible pin names, you can access them with:

io.SAM3U_PIN_NAMES.keys() io.SCHEMATIC_PIN_NAMES.keys() io.FPGA_PIN_NAMES.keys()

pin_set_output(pinname)

Set a given pin as an output.

Parameters

pinname (str) – Name such as “PB22”, “USB_A20”, or “M2”.

pin_set_state(pinname, state)

Set the state of a pin (must have been set as output previously).

Parameters
  • pinname (str) – Name such as “PB22”, “USB_A20”, or “M2”.

  • state (bool) – Set pin high (True) or low (False)

spi1_setpins(sdo, sdi, sck, cs)

Set the pins to be used for the SPI1 interface.

Parameters
  • sdo (str) – Serial Data Out (output from SAM3U) pin name such as “PB22”, “USB_A20”, or “M2”.

  • sdi (str) – Serial Data In (input to SAM3U) pin name such as “PB22”, “USB_A20”, or “M2”.

  • sck (str) – Serial Clock (output from SAM3U) pin name such as “PB22”, “USB_A20”, or “M2”.

  • cs (str) – Chip Select (output from SAM3U) name such as “PB22”, “USB_A20”, or “M2”.

spi1_enable(enable, waitcycles=0)

Enable or disable the SPI interface.

Parameters

enable (bool) – Enable (True) or disable (False) SPI interface

spi1_transfer(data)

Writes data, dropping CS before and raising after, returns read data.

Parameters

data (list) – Write data over the SPI interface

CW310

class CW310(*args, **kwargs)

CW310 Bergen Board target object.

This class contains the public API for the CW310 hardware. To connect to the CW310, the easiest method is:

import chipwhisperer as cw
scope = cw.scope()

# scope can also be None here, unlike with the default SimpleSerial
target = cw.target(scope,
        targets.CW310, bsfile=<valid FPGA bitstream file>)

Inherits the CW305 object, so you can use the same methods as the CW305, provided the register interface in your FPGA build is the same.

You can also set the voltage and current settings for the USB-C Power port on the CW310

# set USB PDO 3 to 20V 5A target.usb_set_voltage(3, 20) target.usb.set_current(3, 5)

# renegotiate PDO (applies above settings) target.usb_negotiate_pdo()

For more help about CW305 settings, try help() on this CW310 submodule:

  • target.pll

usb_set_voltage(pdo_num, voltage)

Set the voltage for one of the USBC PDOs.

PDO1 is always 5V 1A and cannot be changed.

Parameters
  • pdo_num (int) – The PDO to set the voltage for. Can be 2 or 3

  • voltage (float) – The voltage to set. Must be between 5 and 20 inclusive. Has a resolution of 0.05V

usb_set_current(pdo_num, current)

Set the current for one of the USBC PDOs.

PDO1 is always 5V 1A and cannot be changed.

Parameters
  • pdo_num (int) – The PDO to set the current for. Can be 2 or 3

  • voltage (float) – The current to set. Must be between 0.5 and 5 inclusive. Has a resolution of 0.01A

usb_negotiate_pdo()

Renegotate the USBC PDOs. Must be done for new PDOs settings to take effect

gpio_mode(timeout=200)

Allow arbitrary GPIO access on SAM3U

Allows low-level IO access to SAM3U GPIO, and also SPI transfers. (see documentation on the returned object for more info)

Parameters

timeout (int) – USB timeout in ms. Defaults to 200.

Returns

A FPGAIO object which can be used to access IO on the CW305.

_con(scope=None, bsfile=None, force=False, fpga_id=None, defines_files=None, slurp=True, prog_speed=10000000.0)

Connect to CW305 board, and download bitstream.

If the target has already been programmed it skips reprogramming unless forced.

Parameters
  • scope (ScopeTemplate) – An instance of a scope object.

  • bsfile (path) – The path to the bitstream file to program the FPGA with.

  • force (bool) – Whether or not to force reprogramming.

  • fpga_id (string) – ‘100t’, ‘35t’, or None. If bsfile is None and fpga_id specified, program with AES firmware for fpga_id

  • defines_files (list, optional) – path to cw305_defines.v

  • slurp (bool, optional) – Whether or not to slurp the Verilog defines.

fpga_write(addr, data)

Write to an address on the FPGA

Parameters
  • addr (int) – Address to write to

  • data (list) – Data to write to addr

fpga_read(addr, readlen)

Read from an address on the FPGA

Parameters
  • addr (int) – Address to read from

  • readlen (int) – Length of data to read

Returns

Requested data as a list

cdc_settings target.cdc_settings

Check or set whether USART settings can be changed via the USB CDC connection

i.e. whether you can change USART settings (baud rate, 8n1) via a serial client like PuTTY

Getter

An array of length two for the two CDC ports

Setter

Can set either via an integer (which sets both ports) or an array of length 2 (which sets each port)

Returns None if using firmware before the CDC port was added

Program

When testing out different firmware on the target it is useful to be able to reprogram the target. This can be done using the chipwhisperer.program_target() function. There are multiple programmer types available:

  • programmers.STM32FProgrammer

  • programmers.XMEGAProgrammer

  • programmers.AVRProgrammer

program_target(scope, prog_type, fw_path, **kwargs)

Program the target using the programmer <type>

Programmers can be found in the programmers submodule

Parameters
  • scope (ScopeTemplate) – Connected scope object to use for programming

  • prog_type (Programmer) – Programmer to use. See chipwhisperer.programmers for available programmers

  • fw_path (str) – Path to hex file to program

New in version 5.0.1: Simplified programming target

Project

The project is a way of storing a traces, and other project data together using a bag-of-files. These projects can be exported and imported to a new session.

A project can be accessed a few different ways. It can either be loaded from storage, created new, or imported. Importing currently only supports zip files.

open_project(filename)

Load an existing project from disk.

Parameters

filename (str) – Path to project file.

Returns

A chipwhisperer project object.

Raises

OSError – filename does not exist.

create_project(filename, overwrite=False)

Create a new project with the path <filename>.

If <overwrite> is False, raise an OSError if this path already exists.

Parameters
  • filename (str) – File path to create project file at. Must end with .cwp

  • overwrite (bool, optional) – Whether or not to overwrite an existing project with <filename>. Raises an OSError if path already exists and this is false. Defaults to false.

Returns

A chipwhisperer project object.

Raises

OSError – filename exists and overwrite is False.

import_project(filename, file_type='zip', overwrite=False)

Import and open a project.

Will import the filename by extracting to the current working directory.

Currently support file types:
  • zip

Parameters
  • filename (str) – The file name to import.

  • file_type (str) – The type of file that is being imported. Default is zip.

  • overwrite (bool) – Whether or not to overwrite the project given as the import_as project.

New in version 5.1: Add import_project function.

The open_project and the create_project return a Project instance.

class Project(prog_name='ChipWhisperer', prog_ver='')

Class describing an open ChipWhisperer project.

Basic capture usage:

import chipwhisperer as cw
proj = cw.create_project("project")
trace = cw.Trace(trace_data, plaintext, ciphertext, key)
proj.traces.append(trace)
proj.save()

Basic analyzer usage:

import chipwhisperer as cw
import chipwhisperer.analyzer as cwa
proj = cw.open_project("project")
attack = cwa.cpa(proj)
#run attack

Use a trace_manager when analyzing traces, since that allows analyzer to work with multiple trace segments.

location

The directory in which the project is located.

Example:

print(project.location)
'/path/to/the/directory/containing/this/project'
Getter

(str) Returns the file path of the projects parent directory.

New in version 5.1: Added location attribute to project.

traces

The interface to all traces contained in the project.

Instance of Traces.

waves

Iterable for working with only the trace data.

Each item in the iterable is a numpy array.

Supports iterating, indexing, and slicing:

for wave in my_project.waves:
    # do something
textins

Iterable for working with only the text in.

Each item in the iterable is a byte array.

Supports iterating, indexing, and slicing:

for textin in my_project.textins:
    # do something
textouts

Iterable for working with only the text out.

Each item in the iterable is a byte array.

Supports iterating, indexing, and slicing:

for textout in my_project.textouts:
    # do something
keys

Iterable for working with only the known keys.

Each item in the iterable is a byte array.

Supports iterating, indexing, and slicing:

for key in my_project.keys:
    # do something
get_filename()

Gets the filename associated with the project.

Returns

Filename of the project config file ending with “.cwp”.

trace_manager()

Gets the trace manager for the project

Returns

The trace manager for the project

export(file_path, file_type='zip')

Export a chipwhisperer project.

Saves project before exporting.

Supported export types:
  • zip (default)

Returns

(str) Path to the exported file.

New in version 5.1: Add export method to active project.

save()

Saves the project.

Writes the project to the disk. Before this is called your data is not saved. Filenames for traces are set in this method.

close(save=True)

Closes the project cleanly.

Saves by default. Then closes all claimed files.

Parameters

save (bool) – Saves the project before closing.

class Traces(project, segment_length=10000)

Contains the trace interface for the project.

The class adds support for indexing, slicing and iterating of project traces. To add traces to the project use append.

for trace in my_traces:
    my_project.traces.append(trace)

To iterate through all traces use:

for trace in my_project.traces:
    print(trace.wave, trace.textin, trace.textout, trace.key)

Indexing is supported:

trace_of_interest = my_project.traces[99]

So is slicing:

interesting_traces = my_project.traces[20:35]
Parameters
  • project – The project class where traces will be stored.

  • segment_length (int) – The number of traces stored in one file before another file is created. This is used for unloading and loading traces from disk to keep memory usage reasonable.

Returns

(iterable) of traces in the project if the traces belongs to a segment that is enabled. The iterable contains tuples of length four containing the trace, plain text in, encrypted text out, and known key.

Raises
  • IndexError – When the index used for indexing is out of range.

  • TypeError – When key used to get item is not a slice or integer.

New in version 5.1: Added Traces class to project interface.

append(trace)

Append a Trace containing the trace and related operation information.

Parameters

trace (Trace) – A captured or created trace.

Raises

TypeError – When trying to append something other than a trace.

extend(iterable)

Add all traces in an iterable to the project.

Parameters

iterable – Any iterable of Trace objects.

Raises

TypeError – If any of the object in the iterable are not a trace.

Capture

Before capturing a trace make sure:

  1. The scope has been connected.

  2. The scope is configured.

  3. The target has been connected.

  4. The target is configured.

  5. The target has been programmed with the correct firmware.

Once you completed these steps you can use the capture_trace function to complete a capture of one trace. There are some helper classes that generate types of key text patterns for input to the capture_trace function. The function will return a Trace.

capture_trace(scope, target, plaintext, key=None, ack=True, poll_done=False)

Capture a trace, sending plaintext and key

Does all individual steps needed to capture a trace (arming the scope sending the key/plaintext, getting the trace data back, etc.). Uses target.output_len as the length of the expected target reponse for simpleserial.

Parameters
  • scope (ScopeTemplate) – Scope object to use for capture.

  • target (TargetTemplate) – Target object to read/write text from.

  • plaintext (bytearray) – Plaintext to send to the target. Should be unencoded bytearray (will be converted to SimpleSerial when it’s sent). If None, don’t send plaintext.

  • key (bytearray, optional) – Key to send to target. Should be unencoded bytearray. If None, don’t send key. Defaults to None.

  • ack (bool, optional) – Check for ack when reading response from target. Defaults to True.

  • poll_done (bool, optional) – poll Husky to find out when it’s done capturing, instead of calculating the capture time based on the capture parameters. Useful for long trigger-based segmented captures. Can also result in slightly faster captures when the number of samples is high. Defaults to False. Supported by Husky only.

Return type

Optional[Trace]

Returns

Trace or None if capture timed out.

Raises

Warning or OSError – Error during capture.

Example

Capturing a trace:

import chipwhisperer as cw
scope = cw.scope()
scope.default_setup()
target = cw.target()
ktp = cw.ktp.Basic()
key, pt = ktp.new_pair()
trace = cw.capture_trace(scope, target, pt, key)

New in version 5.1: Added to simplify trace capture.

Changed in version 5.2: Added ack parameter and use of target.output_len

Changed in version 5.6.1: Added poll_done parameter for Husky

Trace

This class is used throughout the ChipWhisperer software to package together the relevant data for each captured power trace. After a capture is complete the capture_trace function will return a Trace. This trace is namedtuple of four pieces of data (wave, textin, textout, key), where wave is the actually numpy array of the power trace captured during the target’s operation. The individual pieces of data can be accessed as a one would with a tuple or by using the provided attributes. Example:

import chipwhisperer as cw
trace = cw.Trace(wave, textin, textout, key)

This trace groups together the power trace (wave), and the process information that resulted in that trace such as textin, textout, and key.

class Trace(wave, textin, textout, key)
wave

Alias for field number 0

textin

Alias for field number 1

textout

Alias for field number 2

key

Alias for field number 3

New in version 5.1: Added Trace class.

Key Text Patterns

There are a few different types of classes for generating key text patterns for your capture:

Basic

class AcqKeyTextPattern_Basic

Class for getting basic keys and plaintexts.

Basic usage:

import chipwhisperer as cw
ktp = cw.ktp.Basic()
key, text = ktp.next()
fixed_key

Generate fixed key (True) or not (False).

Getter

Return True if using fixed key or False if not.

Setter

Set whether to use fixed key (True) or not (False).

New in version 5.1: Added fixed_key property

fixed_text

Generate fixed plaintext (True) or not (False).

Getter

Return True if using fixed plaintext or False if not.

Setter

Set whether to use fixed plaintext (True) or not (False).

New in version 5.1: Added fixed_text property

next()

Returns the next key text pair

Updates last key and text

Returns

(key (bytearray), text (bytearray))

New in version 5.1: Added next

next_key()

Returns the next key

Does not update text. If key is fixed, returns the same key as last time

Returns

key (bytearray)

New in version 5.1: Added next_key

next_text()

Returns the next plaintext

Does not update key. If text is fixed, returns the same plaintext as last time

Returns

text (bytearray)

New in version 5.1: Added next_text

TVLA TTest

class AcqKeyTextPattern_TVLATTest(target=None)

Class for getting key and text for TVLA T-Tests.

Basic usage:

import chipwhisperer as cw
ktp = cw.ktp.TVLATTest()
ktp.init(num_traces) # init with the number of traces you plan to
                     # capture
key, text = ktp.next()
init(maxtraces)

Initialize key text pattern for a specific number of traces.

Parameters

maxtraces (int) – Number of traces to initialize for.

Raises

ValueError – Invalid key length

next()

Returns the next key text pair

Updates last key and text

Returns

(key (bytearray), text (bytearray))

New in version 5.1: Added next

Analyzer

You may want to use your captured traces to perform an attack based on a type of side-channel analysis, in comes the analyzer. You can import the analyzer API using:

import chipwhisperer.analyzer as cwa

One of the ways to analyze your traces is using correlation power analysis (CPA). The cpa function returns a CPA object that can be used to run the attack.

analyzer.cpa cpa(proj, leak_model, algorithm=cpa_algorithms.Progressive)
leakage_models

Contains all available leakage models that can be passed to the cpa function as the leak_model parameter.

Instance of the EightBitAES128LeakageModels class.

New in version 5.1: Add leakage_models to anlayzer API.

Preprocessing

Before performing an attack you may want to apply some pre-processing to the captured traces. There is currently one pre-processing class that has been moved to the latest ChipWhisperer API.

class ResyncSAD(trace_source=None)

Resynchronize traces by shifting them to match in a certain window.

This method of pre-processing uses the Sum of Absolute Difference (SAD) algorithm, also known as the Sum of Absolute Error. Uses a portion of one of the traces as a reference. This reference is then slid over the input “window” of each trace, and the amount of the shift resulting in the minimum SAD criteria is used as the shift amount for each trace.

Parameters

trace_source (Project) – A project containing the traces to preprocess.

max_shift

Maximum amount to shift around a trace around the target_window

ref_trace

The trace being used as a reference.

Raises

TypeError – If attempting to set to non integer value.

target_window

Section of the trace we are trying to minimize SAD for.

This must be a tuple of (first point, last point).

Raises

TypeError – If attempting to set to a non tuple or if points are not integers.

preprocess()

Process all traces.

Returns

A new project containing the processed traces.

Return type

Project

Leakage Models

The analyzer includes various leakage models that can be passed to the cpa as the leak_model argument. The leakage_models variable provides a convenient way to list and access all the available leakage models:

import chipwhisperer.analyzer as cwa
print(cwa.leakage_models)

Any attribute can be chosen from this list and accessed with the dot syntax.

class EightBitAES128LeakageModels

Contains the available leakage models for 8 bit AES128.

To use a leakage model during a correlation power analysis attack see cpa.

leakage_models is an instance of this class.

after_key_mix

Hamming weight of 1st round key mix (pt ^ key)

inverse_sbox_output

Hamming weight of 1st round InvSBox (for decryption)

last_round_state

Hamming weight of 9th round state (InvSBox output)

last_round_state_diff

Hamming distance between rounds 9 and 10

last_round_state_diff_alternate

Hamming distance between rounds 9 and 10 (alternate calculation)

mix_columns_output

Hamming weight of 1st round mix columns

plaintext_key_xor

Hamming weight of 1st round key mix (pt ^ key)

round_1_2_state_diff_key_mix

Hamming distance between initial key mix and round 1 key mix

round_1_2_state_diff_sbox

Hamming distance between round 1 and round 2 sbox output

round_1_2_state_diff_text

Hamming distance between AES input and mix columns output

sbox_in_out_diff

Hamming distance between SBox input and output.

sbox_input_successive

Hamming distance between 2 AES sbox inputs

sbox_output

Hamming weight of 1st round SBox output

sbox_output_successive

Hamming distance between 2 AES sbox outputs

shift_rows_output

Hamming weight of shift rows output

new_model(model)

Makes a new leakage model for use with analyzer

Usage:

class AES256_Round13_Model(cwa.AESLeakageHelper):
    def leakage(self, pt, ct, guess, bnum):
        # You must put YOUR recovered 14th round key here.
        # This example may not be accurate!
        calc_round_key = [0xea, 0x79, 0x79, 0x20, 0xc8, 0x71,
                          0x44, 0x7d, 0x46, 0x62, 0x5f, 0x51,
                          0x85, 0xc1, 0x3b, 0xcb]
        xored = [calc_round_key[i] ^ pt[i] for i in range(0, 16)]
        block = xored
        block = self.inv_shiftrows(block)
        block = self.inv_subbytes(block)
        block = self.inv_mixcolumns(block)
        block = self.inv_shiftrows(block)
        result = block
        return self.inv_sbox((result[bnum] ^ guess[bnum]))

leak_model = cwa.leakage_models.new_model(AES256_Round13_Model)
Parameters

model (AESLeakageHelper) – New leakage model to create

Returns

Leakage model made from model

CPA Attack

The interface class to carry out a correlation power analysis attack on the previously captured traces. The easiest way to create a default CPA instance that is ready to perform an attack is to use the cpa function.

class CPA(proj, leak_model, algorithm)

Correlation Power Analysis (CPA).

Provides all the needed functionality for taking a project and performing a CPA attack with a specific type of leakage model.

Parameters
  • proj (Project) – An open project instance.

  • algorithm – The algorithm used for the analysis. Default is Progressive which allows a callback to be given. The callback is called at increments of a specific interval. This is useful for auto-updating tables and equivalent.

  • leak_model – The leakage model used when analysing the captured traces.

The easiest way to use this class is through the cpa API function provided by the chipwhisperer.analyzer module.

Example:

import chipwhisperer.analyzer as cwa
import chipwhisperer as cw
proj = cw.open_project('/path/to/project')
attack = cwa.cpa(proj, cwa.leakage_models.sbox_output)
results = attack.run()
print(results)
project

Project to pull waves, textin, etc. from.

algorithm

Analysis algorithm to use for attack. Should be Progressive

leak_model

Leakage model to use during analysis. Should be of type AESLeakageHelper.

trace_range

Start and end trace number. Should be a list of length 2 (i.e. [start_num, end_num]).

point_range

Range of points to use from waves in project. Should be a list of length 2 ([start_point, end_point]).

subkey_list

List of subkeys to attack (subkey_list = [0, 1, 3] will attack subkeys 0, 1, and 3).

New in version 5.1: Added CPA in cpa_new.py to wrap old CPA object

change_project(proj)

Change the project property and update ranges

If you don’t want to update your ranges, change the project attribute instead.

Parameters

project (Project) – Project to switch to

Returns

None

run(callback=None, update_interval=25)

Runs the attack

Parameters
  • callback (function(), optional) – Callback to call every update interval. No arguments are passed to callback. Defaults to None.

  • update_interval (int, optional) – Number of traces to process before updating the results of the attack.

Returns

Results, the results of the attack. See documentation for Results for more details.

Results

The cpa.run function will return a results object. There are a few methods for interacting with the results object.

class Results(numSubkeys=16, numPerms=256)

Results type used for attacks generating peaks indicating the ‘best’ success. Examples include standard DPA & CPA attacks.

best_guesses()

Gets best subkey guesses from attack results

Returns

List of OrderedDicts with keys ‘guess’, ‘correlation’ and ‘pge’.

find_maximums(bytelist=None, use_absolute=True, use_single=False)

Information from the attack:

Parameters
  • bytelist (list) – Iterable of subkeys to compute and organize results for.

  • use_absolute (bool) – Use absolute value of correlation to find highest correlation.

  • use_single (bool) – All table values are taken from the same point the maximum is taken from.

Returns

Ordered by subkey index:

[subkey0_data, subkey1_data, subkey2_data, ...]

subkey0_data is another list containing guesses ordered by strength of correlation:

[guess0, guess1, guess2, ...]

guess0 is a tuple containing:

(key_guess, location_of_max, correlation)

Return type

list

For example, if you want to print the correlation of the best guess of the 4th subkey, you would run:

print(attack_results.find_maximums()[4][0][2])

Note the “point location of the max” is normally not calculated/tracked, and thus returns as a 0.

key_guess()

Get best guess for key in a list.

Returns

Guessed key as a list

set_known_key(known_key)

Sets the known encryption key.

simple_PGE(bnum)

Returns the partial guessing entropy of subkey.

Utilities

This section contains relatively independent functions that are useful for working with AES, and traces.

AES Functions

You may want to perform certain AES operations seperately. For this there is the AES helper functions. They are accessible using:

from chipwhisperer.analyzer import aes_funcs
Available functions:
sbox(inp)

Perform an SBox lookup.

Parameters

inp (int) – Byte used for the Sbox lookup.

Returns

The result of the SBox lookup.

Return type

int

inv_sbox(inp)

Perform an inverse SBox lookup.

Parameters

inp (int) – Byte used for the inverse Sbox lookup.

Returns

The result of the inverse SBox lookup.

Return type

int

subbytes(inp)

Perform an Sbox lookup for multiple bytes.

Parameters

inp (iterable) – Bytes to perform Sbox lookup on.

Returns

List of bytes resulting from the multiple

SBox lookups.

Return type

list

inv_subbytes(inp)

Perform an inverse Sbox lookup for multiple bytes.

Parameters

inp (iterable) – Bytes to perform inverse Sbox lookup on.

Returns

List of bytes resulting from the multiple

inverse SBox lookups.

Return type

list

shiftrows(state)

AES shift rows operation.

Parameters

state (iterable) – Iterable of 16 bytes.

Returns

List of 16 bytes after shift rows operation.

Return type

list

inv_shiftrows(state)

Inverse AES shift rows operation.

Parameters

state (iterable) – Iterable of 16 bytes.

Returns

List of 16 bytes after inverse shift rows operation.

Return type

list

mixcolumns(state)

AES mix columns operation.

Parameters

state (iterable) – Iterable of 16 bytes.

Returns

List of 16 bytes after mix columns operation.

Return type

list

inv_mixcolumns(state)

AES inverse mix columns operation.

Parameters

state (iterable) – Iterable of 16 bytes.

Returns

List of 16 bytes after inverse mix columns operation.

Return type

list

key_schedule_rounds(input_key, input_round, desired_round)

Use key schedule to determine key for different round.

When dealing with AES-256, inputkey is 16 bytes and inputround indicates round that bytes 0…15 are from.

Parameters
  • input_key (list) – List of bytes of starting key, 16/32 bytes

  • input_round (int) – Starting round number (i.e. 0 = first)

  • desired_round (int) – Desired round number (i.e. 10 = last for 16-byte)

Returns

Key at desired round number. Can go forward or backwards.

Return type

list

Signal to Noise Ratio

Calculate the signal-to-noise ratio of your captured traces:

import chipwhisperer.analyzer as cwa
import chipwhisperer as cw

project = cw.open_project('my_project')
cwa.calculate_snr(project, cwa.leakage_models.sbox_output)
calculate_snr(input, leak_model, bnum=0, db=True)

Calculate the SNR based on the leakage model.

Uses same leakage model as the CPA attack.

Parameters
  • input (Iterable of Traces) – An iterable of traces.

  • leak_model (ModelsBase) – A leakage model selected from leakage_models.

  • bnum (int) – Byte number used for leakage model.

  • bd (bool) – Return signal-to-noise ratio in decibals.