aboutsummaryrefslogtreecommitdiff
path: root/pw_software_update/design.rst
blob: 81fa1b25542662aced4f12df134f5c8ca5519463 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
.. _module-pw_software_update-design:

--------------------------
pw_software_update: Design
--------------------------
.. pigweed-module-subpage::
   :name: pw_software_update
   :tagline: Secure software delivery

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

Embedded TUF
------------

At the heart, the ``pw_software_update`` module leverages
`The Update Framework <https://theupdateframework.io/>`_ (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.

.. mermaid::

   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
^^^^^^^^^^^^^^

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

.. code-block:: text

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

Bundles are encoded as serialized "protocol buffers".

Key structure
^^^^^^^^^^^^^

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``.

.. mermaid::

   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
^^^^^^^^^^^^^^^
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.

.. mermaid::

   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
^^^^^^^^^^^^^^^^^^^

.. mermaid::

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

The :cpp:type:`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
^^^^^^^^^^^^^^^

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

:cpp:type:`BundledUpdateService` is invoked via :ref:`module-pw_rpc` after an
incoming bundle is staged via :ref:`module-pw_transfer`.

.. mermaid::

   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
^^^^^^^

``pw_software_update`` provides the following tooling support for development
and integration.

The python package
~~~~~~~~~~~~~~~~~~
``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.

.. code-block:: text

   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
~~~~~~~~~~~~~~~~~~~~~~~~

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.

.. code-block:: text

   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 :ref:`module-pw_software_update-cli`.