Code documentation

ragger.backend

ragger.backend.interface

Interface contract

The contract a backend must respect:

Response management policy

To change the behavior of the backend on response APDU, one can tinker with the RaisePolicy:

class ragger.backend.interface.RaisePolicy(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
RAISE_ALL = 3
RAISE_ALL_BUT_0x9000 = 2
RAISE_CUSTOM = 4
RAISE_NOTHING = 1

Concrete backends

Speculos backend (emulator)

Physical backends

ragger.error

class ragger.error.ExceptionRAPDU(status: int, data: bytes = b'')

Depending on the RaisePolicy, communication with an application can raise this exception.

Just like RAPDU, it is composed of two attributes:

  • status (int), which is extracted from the two last bytes of the response,

  • data (bytes), which is the entire response payload, except the two last bytes.

ragger.firmware

Most Ragger high-level class needs to know which Firmware they should expect. This is declared with this class:

class ragger.firmware.Firmware(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

NANOS = 1
NANOSP = 2
NANOX = 3
STAX = 4
FLEX = 5
APEX_P = 6
APEX_M = 7
property device: str

A proxy property for Firmware.name. This property is deprecated. It is advise to not use it.

property is_nano

States if the firmware’s name starts with ‘nano’ or not.

property name: str

Returns the name of the current firmware’s device

ragger.firmware.touch

ragger.firmware.touch.screen

ragger.firmware.touch.layouts

ragger.firmware.touch.use_cases

ragger.navigator

Interface and instructions

ragger.utils

ragger.utils.structs

class ragger.utils.structs.RAPDU(status: int, data: bytes)

The dataclass containing the application’s response of an APDU from the client to the application.

It is composed of two attributes:

  • status (int): from the two last bytes of the payload. Common values are 0x9000 for success, other being errors.

  • data (bytes): the rest of the response (the entire payload without the two last bytes)

ragger.utils.misc

ragger.utils.coverage

ragger.utils.coverage.enable(device_name: str, elf: Path, trace_dir: Path) None

Turn on QEMU in_asm tracing for the upcoming Speculos launches.

Sets the QEMU_LOG* environment variables (inherited by the QEMU process Speculos spawns) and registers the (elf, trace_dir) couple for this device so the traces can be converted at the end of the session. %d in the filename is expanded by QEMU to the process pid: the backend is usually class-scoped, so several QEMU instances run and each must write its own file.

ragger.utils.coverage.finalize(project_root: Path, output: Path, readelf: str = 'readelf', exclude: Optional[List[str]] = None) List[Tuple[str, int, int, int, Path, Optional[Path]]]

Convert every registered device’s traces into an lcov file.

For a single device, writes output. For several devices, writes one file per device next to output (<stem>-<device><suffix>). An HTML report is rendered next to each .info (<stem>_html/) whenever genhtml is available; otherwise only the lcov file is produced. exclude removes matching repo-relative source paths (e.g. vendored submodules). Returns the per-device results (rendering of the human-readable summary is left to the caller).

ragger.utils.coverage.to_html(info: Path, html_dir: Path, project_root: Path) Optional[Path]

Render an lcov .info into an HTML report with genhtml.

Run from project_root so the repo-relative SF: paths resolve to their sources. Returns the report’s index.html on success, or None (with a warning) if genhtml is unavailable or failed.

ragger.utils.coverage.to_lcov(elf: Path, trace_files: List[Path], output: Path, project_root: Path, readelf: str = 'readelf', load_base: int = 1073741824, exclude: Optional[List[str]] = None) Tuple[int, int, int]

Convert in_asm traces into an lcov tracefile.

exclude is an optional list of patterns (see _excluded()) removing matching repo-relative source paths, e.g. vendored submodules.

Returns (files, covered_lines, instrumented_lines). Raises ValueError if the ELF has no DWARF line info, or if no app code was executed.