punchboot 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- punchboot-2.0.0/LICENSE +31 -0
- punchboot-2.0.0/PKG-INFO +305 -0
- punchboot-2.0.0/README.md +281 -0
- punchboot-2.0.0/punchboot.egg-info/PKG-INFO +305 -0
- punchboot-2.0.0/punchboot.egg-info/SOURCES.txt +33 -0
- punchboot-2.0.0/punchboot.egg-info/dependency_links.txt +1 -0
- punchboot-2.0.0/punchboot.egg-info/entry_points.txt +2 -0
- punchboot-2.0.0/punchboot.egg-info/requires.txt +2 -0
- punchboot-2.0.0/punchboot.egg-info/top_level.txt +2 -0
- punchboot-2.0.0/pyproject.toml +56 -0
- punchboot-2.0.0/setup.cfg +4 -0
- punchboot-2.0.0/setup.py +96 -0
- punchboot-2.0.0/src/lib/bpak.c +387 -0
- punchboot-2.0.0/src/wire.c +107 -0
- punchboot-2.0.0/tools/punchboot/api.c +54 -0
- punchboot-2.0.0/tools/punchboot/api_authentication.c +123 -0
- punchboot-2.0.0/tools/punchboot/api_board.c +156 -0
- punchboot-2.0.0/tools/punchboot/api_boot.c +257 -0
- punchboot-2.0.0/tools/punchboot/api_device.c +129 -0
- punchboot-2.0.0/tools/punchboot/api_misc.c +46 -0
- punchboot-2.0.0/tools/punchboot/api_partition.c +531 -0
- punchboot-2.0.0/tools/punchboot/api_slc.c +206 -0
- punchboot-2.0.0/tools/punchboot/api_stream.c +268 -0
- punchboot-2.0.0/tools/punchboot/error.c +46 -0
- punchboot-2.0.0/tools/punchboot/exceptions.c +73 -0
- punchboot-2.0.0/tools/punchboot/punchboot/__init__.py +58 -0
- punchboot-2.0.0/tools/punchboot/punchboot/__main__.py +667 -0
- punchboot-2.0.0/tools/punchboot/punchboot/helpers.py +314 -0
- punchboot-2.0.0/tools/punchboot/punchboot/partition.py +59 -0
- punchboot-2.0.0/tools/punchboot/punchboot/py.typed +0 -0
- punchboot-2.0.0/tools/punchboot/punchboot/session.py +414 -0
- punchboot-2.0.0/tools/punchboot/punchboot/slc.py +21 -0
- punchboot-2.0.0/tools/punchboot/python_wrapper.c +1152 -0
- punchboot-2.0.0/tools/punchboot/socket.c +138 -0
- punchboot-2.0.0/tools/punchboot/usb.c +242 -0
punchboot-2.0.0/LICENSE
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Punch BOOT
|
|
2
|
+
|
|
3
|
+
SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
|
|
5
|
+
Copyright 2018, Jonas Blixt <jonpe960@gmail.com>
|
|
6
|
+
|
|
7
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
8
|
+
are permitted provided that the following conditions are met:
|
|
9
|
+
|
|
10
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
11
|
+
this list of conditions and the following disclaimer.
|
|
12
|
+
|
|
13
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
and/or other materials provided with the distribution.
|
|
16
|
+
|
|
17
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
18
|
+
may be used to endorse or promote products derived from this software
|
|
19
|
+
without specific prior written permission.
|
|
20
|
+
|
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
23
|
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
24
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
25
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
26
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
27
|
+
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
28
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
29
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
30
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
31
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
punchboot-2.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: punchboot
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Punchboot tools
|
|
5
|
+
Home-page: https://github.com/jonasblixt/punchboot
|
|
6
|
+
Author: Jonas Blixt
|
|
7
|
+
Author-email: jonpe960@gmail.com
|
|
8
|
+
License: BSD
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
12
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: semver<4,>=3
|
|
23
|
+
Requires-Dist: click<9,>=8
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
[](https://scan.coverity.com/projects/jonpe960-punchboot)
|
|
28
|
+
[](https://github.com/jonasblixt/punchboot/actions/workflows/build.yml)
|
|
29
|
+
[](https://results.pre-commit.ci/latest/github/jonasblixt/punchboot/master)
|
|
30
|
+
[](https://codecov.io/gh/jonasblixt/punchboot)
|
|
31
|
+
[](https://punchboot.readthedocs.io/en/latest/?badge=latest)
|
|
32
|
+
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4XMK2G3TPN3BQ)
|
|
33
|
+
|
|
34
|
+
# Introduction
|
|
35
|
+
|
|
36
|
+
Punchboot is a secure and fast bootloader for embedded systems. It is designed to:
|
|
37
|
+
|
|
38
|
+
- Boot as fast as possible
|
|
39
|
+
- Integrate with the SoC's secure boot functionality
|
|
40
|
+
- Authenticate the next piece of software in the boot chain
|
|
41
|
+
- Support A/B system partitions for atomic updates
|
|
42
|
+
- Support automatic rollbacks
|
|
43
|
+
- Minimize software download time in production
|
|
44
|
+
- Be useful for day-to-day development
|
|
45
|
+
|
|
46
|
+
Punchboot is designed for embedded systems and therefore it has a minimalistic
|
|
47
|
+
apporach. There is no run-time configuration, everything is configured in
|
|
48
|
+
the board files.
|
|
49
|
+
|
|
50
|
+
Punchboot could be useful if you care about the following:
|
|
51
|
+
- Boot speed
|
|
52
|
+
- Secure boot
|
|
53
|
+
- Downloading software quickly in production
|
|
54
|
+
|
|
55
|
+
## Design
|
|
56
|
+
|
|
57
|
+
Punchboot is written in C and some assembler. Currently armv7a and armv8 is supported.
|
|
58
|
+
|
|
59
|
+
The directory layout is as follows:
|
|
60
|
+
|
|
61
|
+
| Folder | Description |
|
|
62
|
+
| ------------ | ----------------------- |
|
|
63
|
+
| /doc | Documentation |
|
|
64
|
+
| /pki | Crypto keys for testing |
|
|
65
|
+
| / | Bootloader source |
|
|
66
|
+
| /src/board | Board support |
|
|
67
|
+
| /src/arch | Architecture support |
|
|
68
|
+
| /src/plat | Platform support |
|
|
69
|
+
| /src/drivers | Drivers |
|
|
70
|
+
| /tools | Tools |
|
|
71
|
+
|
|
72
|
+
Supported architectures:
|
|
73
|
+
|
|
74
|
+
| Architecture | Supported |
|
|
75
|
+
| ------------ | ----------------------- |
|
|
76
|
+
| armv7a | Yes |
|
|
77
|
+
| armv8a | Yes |
|
|
78
|
+
| armv7m | Yes |
|
|
79
|
+
|
|
80
|
+
Supported platforms:
|
|
81
|
+
|
|
82
|
+
| Platform | Supported | USB | EMMC | HW Crypto | Secure Boot | Fusebox |
|
|
83
|
+
| --------------- | -------------------- | --- | ---- | --------- | ----------- | ------- |
|
|
84
|
+
| NXP imx6ul | Yes | Yes | Yes | Yes | Yes | Yes |
|
|
85
|
+
| NXP imx8m | Yes | Yes | Yes | Yes | No | Yes |
|
|
86
|
+
| NXP imx8x | Yes | Yes | Yes | Yes | Yes | Yes |
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
Supported boards:
|
|
90
|
+
|
|
91
|
+
| Board | Supported | More info |
|
|
92
|
+
| -------------------- | ----------------------- | --------- |
|
|
93
|
+
| Jiffy | Fully supported | https://github.com/jonasblixt/jiffy |
|
|
94
|
+
| Bebop | Fully supported | https://github.com/jonasblixt/bebop |
|
|
95
|
+
| Technexion PICO-IMX8M| Partial support | https://www.technexion.com/products/system-on-modules/pico/pico-compute-modules/detail/PICO-IMX8M |
|
|
96
|
+
| NXP IMX8QXP MEK | Fully supported | https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/i.mx-applications-processors/i.mx-8-processors/i.mx-8-multisensory-enablement-kit:i.MX8-MEK |
|
|
97
|
+
|
|
98
|
+
Hardware accelerated signature verification
|
|
99
|
+
|
|
100
|
+
| Platform | RSA4096 | EC secp256r1 | EC secp384r1 | EC secp521 |
|
|
101
|
+
| --------------- | ------- | ------------ | ------------ | ---------- |
|
|
102
|
+
| NXP imx6ul | Yes | Yes | No | No |
|
|
103
|
+
| NXP imx8m | Yes | Yes | No | No |
|
|
104
|
+
| nxp imx8x | yes | yes | yes | yes |
|
|
105
|
+
| nxp imx RT | no | no | no | no |
|
|
106
|
+
|
|
107
|
+
Hardware accelerated hash algorithms
|
|
108
|
+
|
|
109
|
+
| Platform | MD5 | SHA256 | SHA384 | SHA512 |
|
|
110
|
+
| --------------- | --- | ------ | ------ | ------ |
|
|
111
|
+
| NXP imx6ul | Yes | Yes | No | No |
|
|
112
|
+
| NXP imx8m | Yes | Yes | No | No |
|
|
113
|
+
| NXP imx8x | Yes | Yes | Yes | Yes |
|
|
114
|
+
| NXP imx RT | No | No | No | No |
|
|
115
|
+
|
|
116
|
+
## Secure Boot
|
|
117
|
+
|
|
118
|
+
### Typical and simplified secure boot flow
|
|
119
|
+
- ROM loads a set of public keys, calculates the checksum of the keys and compares the result to a fused checksum
|
|
120
|
+
- ROM loads punchboot, calculates checksum and verifies signature using key's in step one
|
|
121
|
+
- Run punchboot
|
|
122
|
+
- Punchboot loads a PBI bundle, calculates the checksum and verifies the signature using built in keys
|
|
123
|
+
- Run next step in boot chain
|
|
124
|
+
|
|
125
|
+
Most SoC:s have a boot rom that includes meachanisms for calculating a checksum
|
|
126
|
+
of the bootloader and cryptographically verifying a signature using a public key
|
|
127
|
+
fused to the device.
|
|
128
|
+
|
|
129
|
+
Normally fuses are a limited resource and therefor a common way is to calculate
|
|
130
|
+
a sha256 checksum of the public key(s) and then store this checksum in fuses,
|
|
131
|
+
this way many different public keys can be stored in a flash memory and every
|
|
132
|
+
time the device boots it will compute a sha256 checksum and compare it to the
|
|
133
|
+
fused checksum.
|
|
134
|
+
|
|
135
|
+
Punchboot is designed to be a part of a secure boot chain. This means that
|
|
136
|
+
the bootloader is cryptographically signed, the ROM code of the SoC must
|
|
137
|
+
support a mechanism to validate this signature, otherwise there is no
|
|
138
|
+
root of trust.
|
|
139
|
+
|
|
140
|
+
When punchboot has been verified it, in turn, will load and verify the next
|
|
141
|
+
software component in the boot chain. The bootloader _only_ supports signed
|
|
142
|
+
binaries.
|
|
143
|
+
|
|
144
|
+
## Testing and integration tests
|
|
145
|
+
Punchboot uses QEMU for all module and integration tests. The 'test' platform
|
|
146
|
+
and board target relies on virtio serial ports and block devices. The punchboot
|
|
147
|
+
cli can be built with a domain socket transport instead of USB for communicating
|
|
148
|
+
with an QEMU environment.
|
|
149
|
+
|
|
150
|
+
The test platform code includes gcov code that calls the QEMU semihosting API
|
|
151
|
+
for storing test coverage data on the host.
|
|
152
|
+
|
|
153
|
+
Building and running tests:
|
|
154
|
+
```
|
|
155
|
+
$ cp configs/test_defconfig .config
|
|
156
|
+
$ make
|
|
157
|
+
$ make check
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Device identity
|
|
161
|
+
|
|
162
|
+
Most modern SoC's provide some kind of unique identity, that is guaranteed to
|
|
163
|
+
be unique for that particular type of SoC / Vendor etc but can not be guarateed
|
|
164
|
+
to be globally unique.
|
|
165
|
+
|
|
166
|
+
Punchboot provides a UUID3 device identity based on a combination of the unique
|
|
167
|
+
data from the SoC and an allocated, random, namspace UUID per platform.
|
|
168
|
+
|
|
169
|
+
When booting a linux system this information is relayed to linux through
|
|
170
|
+
in-line patching of the device-tree.
|
|
171
|
+
The device identity can be found in '/proc/device-tree/chosen/device-uuid'
|
|
172
|
+
|
|
173
|
+
## Command mode
|
|
174
|
+
|
|
175
|
+
Command mode is entered when the system can't boot or if the bootloader is
|
|
176
|
+
forced by a configurable, external event to do so.
|
|
177
|
+
|
|
178
|
+
In the command mode it is possible to update the bootloader, write data to
|
|
179
|
+
partitions and install default settings. From v0.3 and forward
|
|
180
|
+
an 'authentication cookie' must be used to interact with the bootloader to
|
|
181
|
+
prevent malicious activity. The only command that can be executed without
|
|
182
|
+
authentication is listing the device information (including the device UUID)
|
|
183
|
+
|
|
184
|
+
The authentication cookie consists of the device UUID encrypted with one of
|
|
185
|
+
the active key pair's private key.
|
|
186
|
+
|
|
187
|
+
## punchboot tool
|
|
188
|
+
The punchboot CLI is used for interacting with the command mode. A summary of the features available:
|
|
189
|
+
|
|
190
|
+
- Update the bootloader it self
|
|
191
|
+
- Manually start system A or B
|
|
192
|
+
- Activate boot partitions
|
|
193
|
+
- Load image to ram and execute it
|
|
194
|
+
- Display basic device info
|
|
195
|
+
- Configure fuses and GPT parition tables
|
|
196
|
+
- Call board specific functions
|
|
197
|
+
|
|
198
|
+
The tool is written in Python and some parts in C to allow bindings for other
|
|
199
|
+
languages. The tool is built on top of a library to make it possible to integrate
|
|
200
|
+
with other tooling and environments.
|
|
201
|
+
|
|
202
|
+
The tool is distributed through PyPi. Binary wheels are available for Windows,
|
|
203
|
+
Linux and macos (x86_64 and arm64).
|
|
204
|
+
|
|
205
|
+
Install using pypi:
|
|
206
|
+
```
|
|
207
|
+
$ pip install punchboot
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Image format
|
|
211
|
+
Punchboot uses the bitpacker file format (https://github.com/jonasblixt/bpak)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
## Authentication token
|
|
215
|
+
|
|
216
|
+
Punchboot enforces authentication when the SLC (Security Life Cycle) is locked.
|
|
217
|
+
To interact with Punchboot the session must be authenticated by using a password
|
|
218
|
+
or a signed token.
|
|
219
|
+
|
|
220
|
+
The authentication token is generated by hashing the device UUID and signing
|
|
221
|
+
it with one of the active key pairs.
|
|
222
|
+
|
|
223
|
+
Example:
|
|
224
|
+
```
|
|
225
|
+
$ punchboot dev show
|
|
226
|
+
Bootloader version: v0.6.1-40-ga47f-dirty
|
|
227
|
+
Device UUID: 0b177094-6b62-3572-902e-c1de339ecb01
|
|
228
|
+
Board name: pico8ml
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Creating the authentication token using the 'createtoken.sh' script located
|
|
232
|
+
in the tools folder. In this example the private key is stored on a yubikey 5 HSM.
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
$ ./createtoken.sh 0B177094-6B62-3572-902E-C1DE339ECB01 pkcs11 -sha256 "pkcs11:id=%02;type=private"
|
|
236
|
+
engine "pkcs11" set.
|
|
237
|
+
Enter PKCS#11 token PIN for PIV Card Holder pin (PIV_II):
|
|
238
|
+
Enter PKCS#11 key PIN for SIGN key:
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Authenticating the session:
|
|
242
|
+
```
|
|
243
|
+
$ punchboot auth token ./0B177094-6B62-3572-902E-C1DE339ECB01.token <name of a key>
|
|
244
|
+
Signature format: secp256r1
|
|
245
|
+
Hash: sha256
|
|
246
|
+
Authenticating using key index 0 and './0B177094-6B62-3572-902E-C1DE339ECB01.token'
|
|
247
|
+
Read 103 bytes
|
|
248
|
+
Authentication successful
|
|
249
|
+
```
|
|
250
|
+
Now the command mode is fully unlocked. The token is of course only valid for
|
|
251
|
+
the individual unit with that perticular UUID.
|
|
252
|
+
|
|
253
|
+
## Metrics
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
Measurements taken on IMX6UL, running at 528 MHz loading a 400kByte binary.
|
|
257
|
+
|
|
258
|
+
Using hardware accelerators for SHA and RSA signatures:
|
|
259
|
+
|
|
260
|
+
| Parameter | Value | Unit |
|
|
261
|
+
| ----------------- | -------- | ---- |
|
|
262
|
+
| Power On Reset | 28 | ms |
|
|
263
|
+
| Bootloader init | 7 | ms |
|
|
264
|
+
| Blockdev read | 13 | ms |
|
|
265
|
+
| SHA256 Hash | 4 | ms |
|
|
266
|
+
| RSA 4096 Signaure | 5 | ms |
|
|
267
|
+
| | | |
|
|
268
|
+
| Total | 57 | ms |
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
Using libtomcrypt for SHA and RSA:
|
|
272
|
+
|
|
273
|
+
| Parameter | Value | Unit |
|
|
274
|
+
| ----------------- | -------- | ---- |
|
|
275
|
+
| Power On Reset | 28 | ms |
|
|
276
|
+
| Bootloader init | 7 | ms |
|
|
277
|
+
| Blockdev read | 13 | ms |
|
|
278
|
+
| SHA256 Hash | 431 | ms |
|
|
279
|
+
| RSA 4096 Signaure | 567 | ms |
|
|
280
|
+
| | | |
|
|
281
|
+
| Total | 1046 | ms |
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
Measurements taken on IMX8QXP, loading a 14296kByte binary.
|
|
285
|
+
|
|
286
|
+
Using hardware accelerators for SHA and RSA signatures:
|
|
287
|
+
|
|
288
|
+
| Parameter | Value | Unit |
|
|
289
|
+
| -------------------- | -------- | ---- |
|
|
290
|
+
| Power On Reset | 175 | ms |
|
|
291
|
+
| Bootloader init | 6.358 | ms |
|
|
292
|
+
| Blockdev read / hash | 107 | ms |
|
|
293
|
+
| RSA 4096 Signature | 0.676 | ms |
|
|
294
|
+
| Total | 288 | ms |
|
|
295
|
+
|
|
296
|
+
The POR time is off due to some unidentified problem with the SCU firmware.
|
|
297
|
+
A guess would be that this metric should be in the 20ms -range.
|
|
298
|
+
|
|
299
|
+
## Contributing
|
|
300
|
+
|
|
301
|
+
1. Fork the repository
|
|
302
|
+
2. Implement new feature or bugfix on a branch
|
|
303
|
+
3. Implement test case(s) to ensure that future changes do not break legacy
|
|
304
|
+
4. Run checks: cp configs/test_defconfig .config && make check
|
|
305
|
+
5. Create pull request
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
[](https://scan.coverity.com/projects/jonpe960-punchboot)
|
|
4
|
+
[](https://github.com/jonasblixt/punchboot/actions/workflows/build.yml)
|
|
5
|
+
[](https://results.pre-commit.ci/latest/github/jonasblixt/punchboot/master)
|
|
6
|
+
[](https://codecov.io/gh/jonasblixt/punchboot)
|
|
7
|
+
[](https://punchboot.readthedocs.io/en/latest/?badge=latest)
|
|
8
|
+
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4XMK2G3TPN3BQ)
|
|
9
|
+
|
|
10
|
+
# Introduction
|
|
11
|
+
|
|
12
|
+
Punchboot is a secure and fast bootloader for embedded systems. It is designed to:
|
|
13
|
+
|
|
14
|
+
- Boot as fast as possible
|
|
15
|
+
- Integrate with the SoC's secure boot functionality
|
|
16
|
+
- Authenticate the next piece of software in the boot chain
|
|
17
|
+
- Support A/B system partitions for atomic updates
|
|
18
|
+
- Support automatic rollbacks
|
|
19
|
+
- Minimize software download time in production
|
|
20
|
+
- Be useful for day-to-day development
|
|
21
|
+
|
|
22
|
+
Punchboot is designed for embedded systems and therefore it has a minimalistic
|
|
23
|
+
apporach. There is no run-time configuration, everything is configured in
|
|
24
|
+
the board files.
|
|
25
|
+
|
|
26
|
+
Punchboot could be useful if you care about the following:
|
|
27
|
+
- Boot speed
|
|
28
|
+
- Secure boot
|
|
29
|
+
- Downloading software quickly in production
|
|
30
|
+
|
|
31
|
+
## Design
|
|
32
|
+
|
|
33
|
+
Punchboot is written in C and some assembler. Currently armv7a and armv8 is supported.
|
|
34
|
+
|
|
35
|
+
The directory layout is as follows:
|
|
36
|
+
|
|
37
|
+
| Folder | Description |
|
|
38
|
+
| ------------ | ----------------------- |
|
|
39
|
+
| /doc | Documentation |
|
|
40
|
+
| /pki | Crypto keys for testing |
|
|
41
|
+
| / | Bootloader source |
|
|
42
|
+
| /src/board | Board support |
|
|
43
|
+
| /src/arch | Architecture support |
|
|
44
|
+
| /src/plat | Platform support |
|
|
45
|
+
| /src/drivers | Drivers |
|
|
46
|
+
| /tools | Tools |
|
|
47
|
+
|
|
48
|
+
Supported architectures:
|
|
49
|
+
|
|
50
|
+
| Architecture | Supported |
|
|
51
|
+
| ------------ | ----------------------- |
|
|
52
|
+
| armv7a | Yes |
|
|
53
|
+
| armv8a | Yes |
|
|
54
|
+
| armv7m | Yes |
|
|
55
|
+
|
|
56
|
+
Supported platforms:
|
|
57
|
+
|
|
58
|
+
| Platform | Supported | USB | EMMC | HW Crypto | Secure Boot | Fusebox |
|
|
59
|
+
| --------------- | -------------------- | --- | ---- | --------- | ----------- | ------- |
|
|
60
|
+
| NXP imx6ul | Yes | Yes | Yes | Yes | Yes | Yes |
|
|
61
|
+
| NXP imx8m | Yes | Yes | Yes | Yes | No | Yes |
|
|
62
|
+
| NXP imx8x | Yes | Yes | Yes | Yes | Yes | Yes |
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
Supported boards:
|
|
66
|
+
|
|
67
|
+
| Board | Supported | More info |
|
|
68
|
+
| -------------------- | ----------------------- | --------- |
|
|
69
|
+
| Jiffy | Fully supported | https://github.com/jonasblixt/jiffy |
|
|
70
|
+
| Bebop | Fully supported | https://github.com/jonasblixt/bebop |
|
|
71
|
+
| Technexion PICO-IMX8M| Partial support | https://www.technexion.com/products/system-on-modules/pico/pico-compute-modules/detail/PICO-IMX8M |
|
|
72
|
+
| NXP IMX8QXP MEK | Fully supported | https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/i.mx-applications-processors/i.mx-8-processors/i.mx-8-multisensory-enablement-kit:i.MX8-MEK |
|
|
73
|
+
|
|
74
|
+
Hardware accelerated signature verification
|
|
75
|
+
|
|
76
|
+
| Platform | RSA4096 | EC secp256r1 | EC secp384r1 | EC secp521 |
|
|
77
|
+
| --------------- | ------- | ------------ | ------------ | ---------- |
|
|
78
|
+
| NXP imx6ul | Yes | Yes | No | No |
|
|
79
|
+
| NXP imx8m | Yes | Yes | No | No |
|
|
80
|
+
| nxp imx8x | yes | yes | yes | yes |
|
|
81
|
+
| nxp imx RT | no | no | no | no |
|
|
82
|
+
|
|
83
|
+
Hardware accelerated hash algorithms
|
|
84
|
+
|
|
85
|
+
| Platform | MD5 | SHA256 | SHA384 | SHA512 |
|
|
86
|
+
| --------------- | --- | ------ | ------ | ------ |
|
|
87
|
+
| NXP imx6ul | Yes | Yes | No | No |
|
|
88
|
+
| NXP imx8m | Yes | Yes | No | No |
|
|
89
|
+
| NXP imx8x | Yes | Yes | Yes | Yes |
|
|
90
|
+
| NXP imx RT | No | No | No | No |
|
|
91
|
+
|
|
92
|
+
## Secure Boot
|
|
93
|
+
|
|
94
|
+
### Typical and simplified secure boot flow
|
|
95
|
+
- ROM loads a set of public keys, calculates the checksum of the keys and compares the result to a fused checksum
|
|
96
|
+
- ROM loads punchboot, calculates checksum and verifies signature using key's in step one
|
|
97
|
+
- Run punchboot
|
|
98
|
+
- Punchboot loads a PBI bundle, calculates the checksum and verifies the signature using built in keys
|
|
99
|
+
- Run next step in boot chain
|
|
100
|
+
|
|
101
|
+
Most SoC:s have a boot rom that includes meachanisms for calculating a checksum
|
|
102
|
+
of the bootloader and cryptographically verifying a signature using a public key
|
|
103
|
+
fused to the device.
|
|
104
|
+
|
|
105
|
+
Normally fuses are a limited resource and therefor a common way is to calculate
|
|
106
|
+
a sha256 checksum of the public key(s) and then store this checksum in fuses,
|
|
107
|
+
this way many different public keys can be stored in a flash memory and every
|
|
108
|
+
time the device boots it will compute a sha256 checksum and compare it to the
|
|
109
|
+
fused checksum.
|
|
110
|
+
|
|
111
|
+
Punchboot is designed to be a part of a secure boot chain. This means that
|
|
112
|
+
the bootloader is cryptographically signed, the ROM code of the SoC must
|
|
113
|
+
support a mechanism to validate this signature, otherwise there is no
|
|
114
|
+
root of trust.
|
|
115
|
+
|
|
116
|
+
When punchboot has been verified it, in turn, will load and verify the next
|
|
117
|
+
software component in the boot chain. The bootloader _only_ supports signed
|
|
118
|
+
binaries.
|
|
119
|
+
|
|
120
|
+
## Testing and integration tests
|
|
121
|
+
Punchboot uses QEMU for all module and integration tests. The 'test' platform
|
|
122
|
+
and board target relies on virtio serial ports and block devices. The punchboot
|
|
123
|
+
cli can be built with a domain socket transport instead of USB for communicating
|
|
124
|
+
with an QEMU environment.
|
|
125
|
+
|
|
126
|
+
The test platform code includes gcov code that calls the QEMU semihosting API
|
|
127
|
+
for storing test coverage data on the host.
|
|
128
|
+
|
|
129
|
+
Building and running tests:
|
|
130
|
+
```
|
|
131
|
+
$ cp configs/test_defconfig .config
|
|
132
|
+
$ make
|
|
133
|
+
$ make check
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Device identity
|
|
137
|
+
|
|
138
|
+
Most modern SoC's provide some kind of unique identity, that is guaranteed to
|
|
139
|
+
be unique for that particular type of SoC / Vendor etc but can not be guarateed
|
|
140
|
+
to be globally unique.
|
|
141
|
+
|
|
142
|
+
Punchboot provides a UUID3 device identity based on a combination of the unique
|
|
143
|
+
data from the SoC and an allocated, random, namspace UUID per platform.
|
|
144
|
+
|
|
145
|
+
When booting a linux system this information is relayed to linux through
|
|
146
|
+
in-line patching of the device-tree.
|
|
147
|
+
The device identity can be found in '/proc/device-tree/chosen/device-uuid'
|
|
148
|
+
|
|
149
|
+
## Command mode
|
|
150
|
+
|
|
151
|
+
Command mode is entered when the system can't boot or if the bootloader is
|
|
152
|
+
forced by a configurable, external event to do so.
|
|
153
|
+
|
|
154
|
+
In the command mode it is possible to update the bootloader, write data to
|
|
155
|
+
partitions and install default settings. From v0.3 and forward
|
|
156
|
+
an 'authentication cookie' must be used to interact with the bootloader to
|
|
157
|
+
prevent malicious activity. The only command that can be executed without
|
|
158
|
+
authentication is listing the device information (including the device UUID)
|
|
159
|
+
|
|
160
|
+
The authentication cookie consists of the device UUID encrypted with one of
|
|
161
|
+
the active key pair's private key.
|
|
162
|
+
|
|
163
|
+
## punchboot tool
|
|
164
|
+
The punchboot CLI is used for interacting with the command mode. A summary of the features available:
|
|
165
|
+
|
|
166
|
+
- Update the bootloader it self
|
|
167
|
+
- Manually start system A or B
|
|
168
|
+
- Activate boot partitions
|
|
169
|
+
- Load image to ram and execute it
|
|
170
|
+
- Display basic device info
|
|
171
|
+
- Configure fuses and GPT parition tables
|
|
172
|
+
- Call board specific functions
|
|
173
|
+
|
|
174
|
+
The tool is written in Python and some parts in C to allow bindings for other
|
|
175
|
+
languages. The tool is built on top of a library to make it possible to integrate
|
|
176
|
+
with other tooling and environments.
|
|
177
|
+
|
|
178
|
+
The tool is distributed through PyPi. Binary wheels are available for Windows,
|
|
179
|
+
Linux and macos (x86_64 and arm64).
|
|
180
|
+
|
|
181
|
+
Install using pypi:
|
|
182
|
+
```
|
|
183
|
+
$ pip install punchboot
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Image format
|
|
187
|
+
Punchboot uses the bitpacker file format (https://github.com/jonasblixt/bpak)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
## Authentication token
|
|
191
|
+
|
|
192
|
+
Punchboot enforces authentication when the SLC (Security Life Cycle) is locked.
|
|
193
|
+
To interact with Punchboot the session must be authenticated by using a password
|
|
194
|
+
or a signed token.
|
|
195
|
+
|
|
196
|
+
The authentication token is generated by hashing the device UUID and signing
|
|
197
|
+
it with one of the active key pairs.
|
|
198
|
+
|
|
199
|
+
Example:
|
|
200
|
+
```
|
|
201
|
+
$ punchboot dev show
|
|
202
|
+
Bootloader version: v0.6.1-40-ga47f-dirty
|
|
203
|
+
Device UUID: 0b177094-6b62-3572-902e-c1de339ecb01
|
|
204
|
+
Board name: pico8ml
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Creating the authentication token using the 'createtoken.sh' script located
|
|
208
|
+
in the tools folder. In this example the private key is stored on a yubikey 5 HSM.
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
$ ./createtoken.sh 0B177094-6B62-3572-902E-C1DE339ECB01 pkcs11 -sha256 "pkcs11:id=%02;type=private"
|
|
212
|
+
engine "pkcs11" set.
|
|
213
|
+
Enter PKCS#11 token PIN for PIV Card Holder pin (PIV_II):
|
|
214
|
+
Enter PKCS#11 key PIN for SIGN key:
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Authenticating the session:
|
|
218
|
+
```
|
|
219
|
+
$ punchboot auth token ./0B177094-6B62-3572-902E-C1DE339ECB01.token <name of a key>
|
|
220
|
+
Signature format: secp256r1
|
|
221
|
+
Hash: sha256
|
|
222
|
+
Authenticating using key index 0 and './0B177094-6B62-3572-902E-C1DE339ECB01.token'
|
|
223
|
+
Read 103 bytes
|
|
224
|
+
Authentication successful
|
|
225
|
+
```
|
|
226
|
+
Now the command mode is fully unlocked. The token is of course only valid for
|
|
227
|
+
the individual unit with that perticular UUID.
|
|
228
|
+
|
|
229
|
+
## Metrics
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
Measurements taken on IMX6UL, running at 528 MHz loading a 400kByte binary.
|
|
233
|
+
|
|
234
|
+
Using hardware accelerators for SHA and RSA signatures:
|
|
235
|
+
|
|
236
|
+
| Parameter | Value | Unit |
|
|
237
|
+
| ----------------- | -------- | ---- |
|
|
238
|
+
| Power On Reset | 28 | ms |
|
|
239
|
+
| Bootloader init | 7 | ms |
|
|
240
|
+
| Blockdev read | 13 | ms |
|
|
241
|
+
| SHA256 Hash | 4 | ms |
|
|
242
|
+
| RSA 4096 Signaure | 5 | ms |
|
|
243
|
+
| | | |
|
|
244
|
+
| Total | 57 | ms |
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
Using libtomcrypt for SHA and RSA:
|
|
248
|
+
|
|
249
|
+
| Parameter | Value | Unit |
|
|
250
|
+
| ----------------- | -------- | ---- |
|
|
251
|
+
| Power On Reset | 28 | ms |
|
|
252
|
+
| Bootloader init | 7 | ms |
|
|
253
|
+
| Blockdev read | 13 | ms |
|
|
254
|
+
| SHA256 Hash | 431 | ms |
|
|
255
|
+
| RSA 4096 Signaure | 567 | ms |
|
|
256
|
+
| | | |
|
|
257
|
+
| Total | 1046 | ms |
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
Measurements taken on IMX8QXP, loading a 14296kByte binary.
|
|
261
|
+
|
|
262
|
+
Using hardware accelerators for SHA and RSA signatures:
|
|
263
|
+
|
|
264
|
+
| Parameter | Value | Unit |
|
|
265
|
+
| -------------------- | -------- | ---- |
|
|
266
|
+
| Power On Reset | 175 | ms |
|
|
267
|
+
| Bootloader init | 6.358 | ms |
|
|
268
|
+
| Blockdev read / hash | 107 | ms |
|
|
269
|
+
| RSA 4096 Signature | 0.676 | ms |
|
|
270
|
+
| Total | 288 | ms |
|
|
271
|
+
|
|
272
|
+
The POR time is off due to some unidentified problem with the SCU firmware.
|
|
273
|
+
A guess would be that this metric should be in the 20ms -range.
|
|
274
|
+
|
|
275
|
+
## Contributing
|
|
276
|
+
|
|
277
|
+
1. Fork the repository
|
|
278
|
+
2. Implement new feature or bugfix on a branch
|
|
279
|
+
3. Implement test case(s) to ensure that future changes do not break legacy
|
|
280
|
+
4. Run checks: cp configs/test_defconfig .config && make check
|
|
281
|
+
5. Create pull request
|