445 lines
16 KiB
ReStructuredText
445 lines
16 KiB
ReStructuredText
.. _module-pw_software_update:
|
|
|
|
-------------------
|
|
pw_software_update
|
|
-------------------
|
|
|
|
This module provides the following building blocks of a high assurance software
|
|
update system:
|
|
|
|
1. A `TUF <https://theupdateframework.io>`_-based security framework.
|
|
2. A `protocol buffer <https://developers.google.com/protocol-buffers>`_ 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.
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
~$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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.
|
|
|
|
.. code-block:: bash
|
|
|
|
$ 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)
|
|
==========================================
|