xref: /aosp_15_r20/external/pigweed/pw_software_update/design.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_software_update-design:
2
3--------------------------
4pw_software_update: Design
5--------------------------
6.. pigweed-module-subpage::
7   :name: pw_software_update
8
9This page explains the security framing, bundle format and update workflows of
10``pw_software_update``.
11
12Embedded TUF
13------------
14
15At the heart, the ``pw_software_update`` module leverages
16`The Update Framework <https://theupdateframework.io/>`_ (TUF),
17an industry-leading software update security framework that is open, flexible,
18and offers a balanced security and privacy treatment.
19
20The ``pw_software_update`` module implements the following building blocks
21around TUF.
22
23.. mermaid::
24
25   flowchart LR
26          A[/Source/] --> |Build| B[/Target files/]
27          B --> |Assemble & Sign| C[(Update bundle)]
28          C --> |Publish| D[(Available updates)]
29          D --> |OTA| E[Device]
30
31Update bundles
32^^^^^^^^^^^^^^
33
34Update bundles represent software releases packaged ready for delivery. A bundle
35is essentially an archived folder matching the following structure:
36
37.. code-block:: text
38
39   /
40   ├── root_metadata
41   ├── targets_metadata
42   └── targets
43       ├── release_notes.txt
44       ├── manifest.txt
45       ├── rtos.bin
46       └── app.bin
47
48Bundles are encoded as serialized "protocol buffers".
49
50Key structure
51^^^^^^^^^^^^^
52
53As an optimization and trade-off for embedded projects, ``pw_software_update``
54only supports the "root" and "targets" roles, as represented by
55``root_metadata`` and ``targets_metadata``.
56
57.. mermaid::
58
59   flowchart LR
60          A[Verified boot] --> |Embed & Verify| B[/Root key/]
61          B --> |Delegate & Rotate| C[/Targets key/]
62          C --> |Sign| D[/Target files/]
63
64
65The "root" role delegates the "targets" role to directly authorize each release.
66
67The "root" role can regularly rotate the "targets" role, in effect revoking
68older versions once a new release is available.
69
70The "root" role is the "root of trust" for software update and tied into
71verified boot. Due to security risks, ``pw_software_update`` does not use
72persistent metadata caches that are not covered by verified boot.
73
74Signing service
75^^^^^^^^^^^^^^^
76Production signing keys MUST be kept secure and clean. That means we must
77carefully control access, log usage details, and revoke the key if it was
78(accidentally) used to sign a "questionable" build.
79
80This is easier with a signing server built around a key management service.
81
82.. mermaid::
83
84   sequenceDiagram
85     actor Releaser
86
87     Releaser->>Signer: Sign my bundle with my key, please.
88
89     activate Signer
90
91     Signer->>Signer: Check permission.
92     Signer->>Signer: Validate & sign bundle.
93     Signer->>Signer: Log action. Email alerts.
94     Signer-->>Releaser: Done!
95     deactivate Signer
96
97We don't yet have a public-facing service. External users should source their
98own solution.
99
100Bundle verification
101^^^^^^^^^^^^^^^^^^^
102
103.. mermaid::
104
105   flowchart LR
106     A[(Incoming bundle)] --> |UpdateBundleAccessor| B[/Verified target files/]
107
108The :cpp:type:`UpdateBundleAccessor` decodes, verifies, and exposes the target
109files from an incoming bundle. This class hides the details of the bundle
110format and verification flow from callers.
111
112Update workflow
113^^^^^^^^^^^^^^^
114
115On the device side, :cpp:type:`BundledUpdateService` orchestrates an update
116session end-to-end. It drives the backend via a :cpp:type:`BundledUpdateBackend`
117interface.
118
119:cpp:type:`BundledUpdateService` is invoked via :ref:`module-pw_rpc` after an
120incoming bundle is staged via :ref:`module-pw_transfer`.
121
122.. mermaid::
123
124   stateDiagram-v2
125   direction LR
126
127   [*] --> Inactive
128
129   Inactive --> Transferring: Start()
130   Inactive --> Finished: Start() error
131
132   Transferring --> Transferring: GetStatus()
133   Transferring --> Transferred
134   Transferring --> Aborting: Abort()
135   Transferring --> Finished: Transfer error
136
137   Transferred --> Transferred: GetStatus()
138   Transferred --> Verifying: Verify()
139   Transferred --> Verifying: Apply()
140   Transferred --> Aborting: Abort()
141
142   Verifying --> Verifying: GetStatus()
143   Verifying --> Verified
144   Verifying --> Aborting: Abort()
145
146   Verified --> Verified: GetStatus()
147   Verified --> Applying: Apply()
148   Verified --> Aborting: Abort()
149
150   Applying --> Applying: GetStatus()
151   Applying --> Finished: Apply() OK
152   Applying --> Finished: Apply() error
153
154   Aborting --> Aborting: GetStatus()
155   Aborting --> Finished: Abort() OK
156   Aborting --> Finished: Abort() error
157
158   Finished --> Finished: GetStatus()
159   Finished --> Inactive: Reset()
160   Finished --> Finished: Reset() error
161
162
163Tooling
164^^^^^^^
165
166``pw_software_update`` provides the following tooling support for development
167and integration.
168
169The python package
170~~~~~~~~~~~~~~~~~~
171``pw_software_update`` comes with a python package of the same name, providing
172the following functionalities.
173
174- Local signing key generation for development.
175- TUF root metadata generation and signing.
176- Bundle generation, signing, and verification.
177- Signing server integration.
178
179A typical use of the package is for build system integration.
180
181.. code-block:: text
182
183   Help on package pw_software_update:
184
185   NAME
186          pw_software_update - pw_software_update
187
188   PACKAGE CONTENTS
189          bundled_update_pb2
190          cli
191          dev_sign
192          generate_test_bundle
193          keys
194          metadata
195          remote_sign
196          root_metadata
197          tuf_pb2
198          update_bundle
199          update_bundle_pb2
200          verify
201
202
203The command line utility
204~~~~~~~~~~~~~~~~~~~~~~~~
205
206The ``pw update ...`` CLI (Command Line Interface) is a user-friendly interface
207to the ``pw_software_update`` python package.
208
209You can use the CLI to quickly learn and prototype a software update system
210based on ``pw_software_update`` on your development PC before productionizing
211one. In the future you will be able to use the CLI to update a reference
212target.
213
214.. code-block:: text
215
216   usage: pw update [sub-commands]
217
218   sub-commands:
219
220          generate-key
221          create-root-metadata
222          sign-root-metadata
223          inspect-root-metadata
224          create-empty-bundle
225          add-root-metadata-to-bundle
226          add-file-to-bundle
227          sign-bundle
228          inspect-bundle
229
230   options:
231          -h, --help            show this help message and exit
232
233
234To learn more, see :ref:`module-pw_software_update-cli`.
235