pw_software_update: Design#

Pigweed AI summary: The pw_software_update module leverages The Update Framework (TUF) for secure software delivery. The module implements building blocks around TUF, including update bundles, key structure, a signing service, bundle verification, and an update workflow. The module also provides tooling support through a python package and a command line interface. The python package includes functionalities such as local signing key generation, TUF root metadata generation and signing, bundle generation, signing, and verification, and signing server integration. The CLI

This page explains the security framing, bundle format and update workflows of pw_software_update.

Embedded TUF#

Pigweed AI summary: The pw_software_update module uses The Update Framework (TUF) to provide a secure and flexible software update system for embedded projects. The module implements building blocks around TUF, including update bundles, key structure, a signing service, bundle verification, and an update workflow. The module also provides tooling support, including a python package and a command line interface for generating keys, creating metadata, signing bundles, and more.

At the heart, the pw_software_update module leverages The Update Framework (TUF), an industry-leading software update security framework that is open, flexible, and offers a balanced security and privacy treatment.

The pw_software_update module implements the following building blocks around TUF.

flowchart LR A[/Source/] --> |Build| B[/Target files/] B --> |Assemble & Sign| C[(Update bundle)] C --> |Publish| D[(Available updates)] D --> |OTA| E[Device]

Update bundles#

Pigweed AI summary: This section discusses update bundles, which are software releases packaged for delivery. These bundles are structured as archived folders and include root and target metadata, release notes, manifest, and binary files. The bundles are encoded as serialized "protocol buffers."

Update bundles represent software releases packaged ready for delivery. A bundle is essentially an archived folder matching the following structure:

/
├── root_metadata
├── targets_metadata
└── targets
    ├── release_notes.txt
    ├── manifest.txt
    ├── rtos.bin
    └── app.bin

Bundles are encoded as serialized “protocol buffers”.

Key structure#

Pigweed AI summary: The software update optimization for embedded projects, pw_software_update, only supports the "root" and "targets" roles represented by root_metadata and targets_metadata. The "root" role delegates the "targets" role to authorize each release and can rotate the "targets" role to revoke older versions. The "root" role is the "root of trust" for software update and is tied into verified boot. To avoid security risks, pw_software_update does not use persistent metadata caches not covered by

As an optimization and trade-off for embedded projects, pw_software_update only supports the “root” and “targets” roles, as represented by root_metadata and targets_metadata.

flowchart LR A[Verified boot] --> |Embed & Verify| B[/Root key/] B --> |Delegate & Rotate| C[/Targets key/] C --> |Sign| D[/Target files/]

The “root” role delegates the “targets” role to directly authorize each release.

The “root” role can regularly rotate the “targets” role, in effect revoking older versions once a new release is available.

The “root” role is the “root of trust” for software update and tied into verified boot. Due to security risks, pw_software_update does not use persistent metadata caches that are not covered by verified boot.

Signing service#

Pigweed AI summary: The signing service requires production signing keys to be kept secure and controlled, with usage details logged and keys revoked if necessary. A signing server with a key management service can make this process easier. The service involves a releaser requesting a bundle to be signed by a signer, who checks permission, validates and signs the bundle, logs the action, and sends email alerts. There is currently no public-facing service available, so external users must find their own solution.

Production signing keys MUST be kept secure and clean. That means we must carefully control access, log usage details, and revoke the key if it was (accidentally) used to sign a “questionable” build.

This is easier with a signing server built around a key management service.

sequenceDiagram actor Releaser Releaser->>Signer: Sign my bundle with my key, please. activate Signer Signer->>Signer: Check permission. Signer->>Signer: Validate & sign bundle. Signer->>Signer: Log action. Email alerts. Signer-->>Releaser: Done! deactivate Signer

We don’t yet have a public-facing service. External users should source their own solution.

Bundle verification#

Pigweed AI summary: The UpdateBundleAccessor class is responsible for decoding, verifying, and exposing the target files from an incoming bundle. It hides the details of the bundle format and verification flow from callers.

flowchart LR A[(Incoming bundle)] --> |UpdateBundleAccessor| B[/Verified target files/]

The UpdateBundleAccessor decodes, verifies, and exposes the target files from an incoming bundle. This class hides the details of the bundle format and verification flow from callers.

Update workflow#

Pigweed AI summary: The BundledUpdateService manages the update process on the device side, using the BundledUpdateBackend interface. It is invoked through pw_rpc after an incoming bundle is staged via pw_transfer. The update process is represented by a state diagram, with various states such as Transferring, Verifying, and Applying, and corresponding actions such as GetStatus, Verify, and Apply. The process can also be aborted or reset if necessary.

On the device side, BundledUpdateService orchestrates an update session end-to-end. It drives the backend via a BundledUpdateBackend interface.

BundledUpdateService is invoked via pw_rpc after an incoming bundle is staged via pw_transfer.

stateDiagram-v2 direction LR [*] --> Inactive Inactive --> Transferring: Start() Inactive --> Finished: Start() error Transferring --> Transferring: GetStatus() Transferring --> Transferred Transferring --> Aborting: Abort() Transferring --> Finished: Transfer error Transferred --> Transferred: GetStatus() Transferred --> Verifying: Verify() Transferred --> Verifying: Apply() Transferred --> Aborting: Abort() Verifying --> Verifying: GetStatus() Verifying --> Verified Verifying --> Aborting: Abort() Verified --> Verified: GetStatus() Verified --> Applying: Apply() Verified --> Aborting: Abort() Applying --> Applying: GetStatus() Applying --> Finished: Apply() OK Applying --> Finished: Apply() error Aborting --> Aborting: GetStatus() Aborting --> Finished: Abort() OK Aborting --> Finished: Abort() error Finished --> Finished: GetStatus() Finished --> Inactive: Reset() Finished --> Finished: Reset() error

Tooling#

Pigweed AI summary: The pw_software_update tool provides support for development and integration, including a Python package with functionalities such as local signing key generation, TUF root metadata generation and signing, bundle generation, signing, and verification, and signing server integration. The package is typically used for build system integration. The pw update CLI is a user-friendly interface to the pw_software_update package, allowing for quick learning and prototyping of a software update system before productionizing one. The CLI includes sub-commands for various tasks

pw_software_update provides the following tooling support for development and integration.

The python package#

Pigweed AI summary: The "pw_software_update" python package provides functionalities such as local signing key generation, TUF root metadata generation and signing, bundle generation, signing, and verification, and signing server integration. It is typically used for build system integration. The package includes various modules such as "cli," "keys," "metadata," and "verify."

pw_software_update comes with a python package of the same name, providing the following functionalities.

  • Local signing key generation for development.

  • TUF root metadata generation and signing.

  • Bundle generation, signing, and verification.

  • Signing server integration.

A typical use of the package is for build system integration.

Help on package pw_software_update:

NAME
       pw_software_update - pw_software_update

PACKAGE CONTENTS
       bundled_update_pb2
       cli
       dev_sign
       generate_test_bundle
       keys
       metadata
       remote_sign
       root_metadata
       tuf_pb2
       update_bundle
       update_bundle_pb2
       verify

The command line utility#

Pigweed AI summary: The pw update CLI is a user-friendly interface for the pw_software_update python package. It can be used to prototype a software update system on a development PC before productionizing one, and in the future, it can be used to update a reference target. The CLI offers various sub-commands and options, which can be explored further in the pw_software_update: CLI reference.

The pw update ... CLI (Command Line Interface) is a user-friendly interface to the pw_software_update python package.

You can use the CLI to quickly learn and prototype a software update system based on pw_software_update on your development PC before productionizing one. In the future you will be able to use the CLI to update a reference target.

usage: pw update [sub-commands]

sub-commands:

       generate-key
       create-root-metadata
       sign-root-metadata
       inspect-root-metadata
       create-empty-bundle
       add-root-metadata-to-bundle
       add-file-to-bundle
       sign-bundle
       inspect-bundle

options:
       -h, --help            show this help message and exit

To learn more, see pw_software_update: CLI reference.