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:
scopes.OpenADC
(Pro and Lite)scopes.CWNano
(Nano)
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
- 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(scope_type=cw.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:
scope.adc.stream_mode (see scope.adc for more information)
- 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. This shows how ChipWhisperer is driving this pin; it does not show its actual logic level. Use scope.io.tio_states to see the actual logic level.
- 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. This shows how ChipWhisperer is driving this pin; it does not show its actual logic level. Use scope.io.tio_states to see the actual logic level.
- 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. This shows how ChipWhisperer is driving this pin; it does not show its actual logic level. Use scope.io.tio_states to see the actual logic level.
- 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. This shows how ChipWhisperer is driving this pin; it does not show its actual logic level. Use scope.io.tio_states to see the actual logic level.
- 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 function 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”. This shows how ChipWhisperer is driving this pin; it does not show its actual logic level.
- 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. N/A for ‘trace’ trigger module (see scope.trace.trace_mode for how to connect trace pins.)
- 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 (N/A 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. Minimum width is obtained at 0. Maximum width is obtained at scope.glitch.phase_shift_steps/2. Negative values are allowed, but -x is equivalent to scope.glitch.phase_shift_steps-x. The setting rolls over (+x is equivalent to scope.glitch.phase_shift_steps+x). Run the notebook in jupyter/demos/husky_glitch.ipynb to visualize glitch settings.
For other capture hardware (CW-lite, CW-pro), 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 an int (Husky) or float (others) with the current glitch width.
- Setter
Update the glitch pulse width. For CW-lite/pro, the value is adjusted to the closest possible glitch width.
- Raises
UserWarning – Width outside of [-49.8, 49.8]. The value is rounded to one of these. (CW-lite/pro only)
- GlitchSettings.width_fine scope.glitch.width_fine¶
The fine adjustment value on the glitch width. N/A for Husky.
This is a dimensionless number that makes small adjustments to the glitch pulses’ width. Valid range is [-255, 255].
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.
For CW-Husky, offset is expressed as the number of phase shift steps. Minimum offset is obtained at 0 (rising edge of glitch aligned with rising edge of glitch source clock). At scope.glitch.phase_shift_steps/2, the glitch rising edge is aligned with the glitch source clock falling edge. Negative values are allowed, but -x is equivalent to scope.glitch.phase_shift_steps-x. The setting rolls over (+x is equivalent to scope.glitch.phase_shift_steps+x). Run the notebook in jupyter/demos/husky_glitch.ipynb to visualize glitch settings.
For other capture hardware (CW-lite, CW-pro), offset is expressed 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.
Warning
very large negative offset <-45 may result in double glitches (CW-lite/pro only).
- Getter
Return an int (Husky) or float (CW-lite/pro) with the current glitch offset.
- Setter
Set the glitch offset. For CW-lite/pro, the new value is rounded to the nearest possible offset.
- Raises
UserWarning – value outside range [-50, 50] (value is rounded) (CW-lite/pro only)
- GlitchSettings.offset_fine scope.glitch.offset_fine¶
The fine adjustment value on the glitch offset. N/A for Husky.
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. The following
scope.glitch parameters have no bearing in this mode: ext_offset, repeat, num_glitches.
- “manual”: Only trigger glitches by calling manual_trigger(). The
following scope.glitch parameters have no bearing in this mode: ext_offset, num_glitches.
- “ext_single”: Use the trigger module. Once the scope is armed, one
set of glitch events is emitted when the trigger condition is satisfied. Subsequent trigger conditions are ignored unless the scope is re-armed.
- “ext_continuous”: Use the trigger module. A set of glitch events is
emitted each time the trigger condition is satisfied, whether or not the scope is armed.
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.
For CW-Husky when scope.glitch.num_glitches > 1, this parameter is a list with scope.glitch.num_glitches elements, each element representing the ext_offset value for the corresponding glitch.
For CW-Lite/Pro, scope.glitch.num_glitches is not supported so this is a simply an integer.
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(s). For CW-lite/pro or when num_glitches=1, this is an integer (for backwards compatibility). Otherwise, it is a list of integers.
- Setter
Set the external trigger offset(s). Integer for CW-lite/pro, list of integers for Husky.
- Raises
TypeError – if offset not an integer, or list of integers for Husky
ValueError – if any 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).
For CW-Husky when scope.glitch.num_glitches > 1, this parameter is a list with scope.glitch.num_glitches elements, each element representing the repeat value for the corresponding glitch.
For CW-Lite/Pro, scope.glitch.num_glitches is not supported so this is a simply an integer.
Has no effect when trigger_src = ‘continuous’.
Repeat counter must be in the range [1, 8192].
- Getter
Return the current repeat value. For CW-lite/pro or when num_glitches=1, this is an integer (for backwards compatibility). Otherwise, it is a list of integers.
- Setter
Set the repeat counter. Integer for CW-lite/pro, list of integers for Husky.
- Raises
TypeError – if value not an integer, or list of integers for Husky
ValueError – if any 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:
Attach the scope part of the hardware to your computer.
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)
Call the auto_program() method:
programmer = cw.SAMFWLoader(scope=scope) # if CW305 # programmer = cw.SAMFWLoader(scope=target) programmer.auto_program()
Example
Attach the scope part of the hardware to your computer.
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)
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)
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)
Program the SAM3U with:
import chipwhisperer as cw programmer = cw.SAMFWLoader(scope=None)
Two methods:
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>)
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#)
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:
Simple Serial Target (default)
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:
It’s easy to reset communications by sending frame bytes (0x00)
- 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
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.
- 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, dtype=<class 'numpy.float64'>)¶
Append a Trace containing the trace and related operation information.
- Parameters
trace (
Trace
) – A captured or created trace.dtype – Numpy data type for storing trace.wave
- 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:
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, as_int=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.
as_int (bool, optional) – If False, return trace as a float. Otherwise, return as an int.
- 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.
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.
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 thechipwhisperer.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.