pw_software_update#

This module provides the following building blocks of a high assurance software update system:

  1. A TUF-based security framework.

  2. A protocol buffer based software update “bundle” format.

  3. An update bundle decoder and verification stack.

  4. An extensible software update RPC service.

High assurance software update#

On a high-level, a high-assurance software update system should make users feel safe to use and be technologically worthy of user’s trust over time. In particular it should demonstrate the following security and privacy properties.

  1. The update packages are generic, sufficiently qualified, and officially signed with strong insider attack guardrails.

  2. The update packages are delivered over secure channels.

  3. Update checking, changelist, and installation are done with strong user authorization and awareness.

  4. Incoming update packages are strongly authenticated by the client.

  5. Software update requires and builds on top of verified boot.

Life of a software update#

The following describes a typical software update sequence of events. The focus is not to prescribe implementation details but to raise awareness in subtle security and privacy considerations.

Stage 0: Product makers create and publish updates#

A (system) software update is essentially a new version of the on-device software stack. Product makers create, qualify and publish new software updates to deliver new experiences or bug fixes to users.

While not visible to end users, the product maker team is expected to follow widely agreed security and release engineering best practices before signing and publishing a new software update. A new software update should be generic for all devices, rather than targeting specific devices.

Stage 1: Users check for updates#

For most consumer products, software updates are “opt-in”, which means users either manually check for new updates or opt-in for the device itself to check (and/or install) updates automatically on the user’s behalf. The opt-in may be blanket or conditioned on the nature of the updates.

If users have authorized automatic updates, update checking also happens on a regular schedule and at every reboot.

Important

As a critical security recovery mechanism, checking and installing software updates ideally should happen early in boot, where the software stack has been freshly verified by verified boot and minimum mutable input is taken into account in update checking and installation.

In other words, the longer the system has been running (up), the greater the chance that system has been taken control by an attacker. So it is a good idea to remind users to reboot when the system has been running for “too long”.

Stage 2: Users install updates#

Once a new update has been determined to be available for the device, users will be prompted to authorize downloading and installing the update. Users can also opt-in to automatic downloading and installing.

Important

If feasible, rechecking, downloading and installing an update should be carried out early in a reboot – to recover from potential temporary attacker control.

To improve reliability and reduce disruption, modern system updates typically employ an A/B update mechanism, where the incoming update is installed into a backup boot slot, and only enacted and locked down (anti-rollback) after the new slot has passed boot verification and fully booted into a good state.

Important

While a system update is usually carried out by a user space update client, an incoming update may contain more than just the user space. It could contain firmware for the bootloader, trusted execution environment, DSP, sensor cores etc. which could be important components of a device’s TCB ( trusted compute base, where critical device security policies are enforced). When updating these components across different domains, it is best to let each component carry out the actual updating, some of which may require stronger user authorization (e.g. a test of physical presence, explicit authorization with an admin passcode etc.)

Lastly, updates should be checked again in case there are newer updates available.

Command-line Interface#

You can access the software update CLI by running pw update in the pigweed environment.

~$ cd pigweed
~/pigweed$ source ./activate.sh
~/pigweed$ pw update

usage: pw update [-h] <command>

Software update related operations.

positional arguments:
    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
    verify-bundle

optional arguments:
  -h, --help            show this help message and exit

Learn more at: pigweed.dev/pw_software_update

generate-key#

The generate-key subcommmand generates an ECDSA SHA-256 public + private keypair.

$ pw update generate-key -h

usage: pw update generate-key [-h] pathname

Generates an ecdsa-sha2-nistp256 signing key pair (private + public)

positional arguments:
  pathname    Path to generated key pair

optional arguments:
  -h, --help  show this help message and exit

positional argument

pathname

path to the generated keypair

create-root-metadata#

The create-root-metadata subcommand creates a root metadata.

$ pw update create-root-metadata -h

usage: pw update create-root-metadata [-h] [--version VERSION] --append-root-key ROOT_KEY
       --append-targets-key TARGETS_KEY -o/--out OUT

Creation of root metadata

optional arguments:
  -h, --help                        show this help message and exit
  --version VERSION                 Canonical version number for rollback checks;
                                    Defaults to 1

required arguments:
  --append-root-key ROOT_KEY        Path to root key
  --append-targets-key TARGETS_KEY  Path to targets key
  -o OUT, --out OUT                 Path to output file

required arguments

--append-root-key

path to desired root key

--append-targets-key

path to desired target key

--out

output path of newly created root metadata

optional argument

--version

Rollback version number(default set to 1)

sign-root-metadata#

The sign-root-metadata subcommand signs a given root metadata.

usage: pw update sign-root-metadata [-h] --root-metadata ROOT_METADATA --root-key ROOT_KEY

Signing of root metadata

optional arguments:
  -h, --help                     show this help message and exit

required arguments:
  --root-metadata ROOT_METADATA  Root metadata to be signed
  --root-key ROOT_KEY            Root signing key

required arguments

--root-metadata

Path of root metadata to be signed

--root-key

Path to root signing key

inspect-root-metadata#

The inspect-root-metadata subcommand prints the contents of a given root metadata.

$ pw update inspect-root-metadata -h

usage: pw update inspect-root-metadata [-h] pathname

Outputs contents of root metadata

positional arguments:
  pathname    Path to root metadata

optional arguments:
  -h, --help  show this help message and exit

positional argument

pathname

Path to root metadata

create-empty-bundle#

The create-empty-bundle subcommand creates an empty update bundle.

$ pw update create-empty-bundle -h

usage: pw update create-empty-bundle [-h] [--target-metadata-version VERSION] pathname

Creation of an empty bundle

positional arguments:
  pathname                           Path to newly created empty bundle

optional arguments:
  -h, --help                         show this help message and exit
  --target-metadata-version VERSION  Version number for targets metadata;
                                     Defaults to 1

positional argument

pathname

Path to newly created empty bundle

optional arguments

--target-metadata-version

Version number for targets metadata;

Defaults to 1

add-root-metadata-to-bundle#

The add-root-metadata-to-bundle subcommand adds a root metadata to a bundle.

$ pw update add-root-metadata-to-bundle -h

usage: pw update add-root-metadata-to-bundle [-h] --append-root-metadata ROOT_METADATA
       --bundle BUNDLE

Add root metadata to a bundle

optional arguments:
  -h, --help                            show this help message and exit

required arguments:
  --append-root-metadata ROOT_METADATA  Path to root metadata
  --bundle BUNDLE                       Path to bundle

required arguments

--append-root-metadata

Path to root metadata

--bundle

Path to bundle

add-file-to-bundle#

The add-file-to-bundle subcommand adds a target file to an existing bundle.

$ pw update add-file-to-bundle -h

usage: pw update add-file-to-bundle [-h] [--new-name NEW_NAME] --bundle BUNDLE
       --file FILE_PATH

Add a file to an existing bundle

optional arguments:
  -h, --help           show this help message and exit
  --new-name NEW_NAME  Optional new name for target

required arguments:
  --bundle BUNDLE      Path to an existing bundle
  --file FILE_PATH     Path to a target file

required arguments

--file

Path to a target file

--bundle

Path to bundle

optional argument

--new-name

Optional new name for target

sign-bundle#

The sign-bundle subcommand signs an existing bundle with a dev key.

$ pw update sign-bundle -h

usage: pw update sign-bundle [-h] --bundle BUNDLE --key KEY

Sign an existing bundle using a development key

optional arguments:
  -h, --help       show this help message and exit

required arguments:
  --bundle BUNDLE  Bundle to be signed
  --key KEY        Bundle signing key

required arguments

--key

Key to sign bundle

--bundle

Path to bundle

inspect-bundle#

The inspect-bundle subcommand prints the contents of a given bundle.

$ pw update inspect-bundle -h

usage: pw update inspect-bundle [-h] pathname

Outputs contents of bundle

positional arguments:
  pathname    Path to bundle

optional arguments:
  -h, --help  show this help message and exit

positional argument

pathname

Path to bundle

verify-bundle#

The verify-bundle subcommand performs verification of an existing bundle.

$ pw update verify-bundle -h

usage: pw update verify-bundle [-h] --bundle BUNDLE
       --trusted-root-metadata ROOT_METADATA

Verify a bundle

optional arguments:
  -h, --help                             show this help message and exit

required arguments:
  --bundle BUNDLE                        Bundle to be verified
  --trusted-root-metadata ROOT_METADATA  Trusted root metadata

required arguments

--trusted-root-metadata

Trusted root metadata(anchor)

--bundle

Path of bundle to be verified

Getting started with bundles (coming soon)#