Capture API#
This page documents the included helper functions and classes for capturing, storing, and plotting traces.
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.
- chipwhisperer.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.
- chipwhisperer.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.
- chipwhisperer.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.
Added in version 5.1: Add import_project function.
The open_project
and the
create_project
return a
Project
instance.
- class chipwhisperer.common.api.ProjectFormat.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.
- close(save=True)#
Closes the project cleanly.
Saves by default. Then closes all claimed files.
- Parameters:
save (bool) – Saves the project before closing.
- 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.
Added in version 5.1: Add export method to active project.
- get_filename()#
Gets the filename associated with the project.
- Returns:
Filename of the project config file ending with “.cwp”.
- property 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
- property 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.
Added in version 5.1: Added location attribute to 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.
- property 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
- property 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
- trace_manager()#
Gets the trace manager for the project
- Returns:
The trace manager for the project
- property 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
- class chipwhisperer.common.api.ProjectFormat.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.
Added in version 5.1: Added Traces class to project interface.
Capture#
Before capturing a trace make sure:
The scope has been connected.
The scope is configured.
The target has been connected.
The target is configured.
The target has been programmed with the correct firmware.
Once you completed these steps you can use the
capture_trace
function to complete a
capture of one trace. There are some helper classes that generate types of
key text patterns for input to the
capture_trace
function. The function
will return a Trace.
- chipwhisperer.capture_trace(scope, target, plaintext, key=None, ack=True, poll_done=False, as_int=False, always_send_key=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.
always_send_key (bool, optional) – If True, always send key. Otherwise, only send if the key is different from the last one sent.
- 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)
Added in version 5.1: Added to simplify trace capture.
Changed in version 5.2: Added ack parameter and use of target.output_len
Changed in version 5.6.1: Added poll_done parameter for Husky
Trace#
This class is used throughout the ChipWhisperer software to package together
the relevant data for each captured power trace. After a capture is complete the
capture_trace
function will return
a Trace
. This trace is namedtuple of four
pieces of data (wave, textin, textout, key), where wave is the actually
numpy array of the power trace captured during the target’s operation. The
individual pieces of data can be accessed as a one would with a tuple or
by using the provided attributes. Example:
import chipwhisperer as cw
trace = cw.Trace(wave, textin, textout, key)
This trace groups together the power trace (wave), and the process information that resulted in that trace such as textin, textout, and key.
- class chipwhisperer.common.traces.Trace(wave, textin, textout, key)#
- key#
Alias for field number 3
- textin#
Alias for field number 1
- textout#
Alias for field number 2
- wave#
Alias for field number 0
Added in version 5.1: Added Trace class.
Key Text Patterns#
There are a few different types of classes for generating key text patterns for your capture:
chipwhisperer.capture.acq_patterns.basic.AcqKeyTextPattern_Basic
chipwhisperer.capture.acq_patterns.tvlattest.AcqKeyTextPattern_TVLATTest
Basic#
- class chipwhisperer.capture.acq_patterns.basic.AcqKeyTextPattern_Basic#
Class for getting basic keys and plaintexts.
Basic usage:
import chipwhisperer as cw ktp = cw.ktp.Basic() key, text = ktp.next()
- property 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).
Added in version 5.1: Added fixed_key property
- 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).
Added in version 5.1: Added fixed_text property
- new_pair()#
Called when a new encryption pair is requested
- next()#
Returns the next key text pair
Updates last key and text
- Returns:
(key (bytearray), text (bytearray))
Added 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)
Added 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)
Added in version 5.1: Added next_text
TVLA TTest#
- class chipwhisperer.capture.acq_patterns.tvlattest.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
- new_pair()#
Called when a new encryption pair is requested
- next()#
Returns the next key text pair
Updates last key and text
- Returns:
(key (bytearray), text (bytearray))
Added in version 5.1: Added next