blob: 63a12f2630b5929068a3c8bf3a050fc92d6d32df [file] [log] [blame]
Abhi Singh1f325e82024-10-21 13:21:42 -05001Measured Boot using a Discrete TPM (PoC)
2========================================
3
4Measured Boot is the process of cryptographically measuring the code and
5critical data used at boot time, for example using a TPM, so that the
6security state can be attested later.
7
8The current implementation of the driver included in |TF-A| supports several
9backends and each has a different means to store the measurements.
10This section focuses on the Discrete TPM backend, which stores measurements
11in a PCR within the TPM. This backend can be paired with the `TCG event log`_
12to provide attestation of the measurements stored in the event log. See
13details in :ref:`Measured Boot Design`.
14
15This section provides instructions to setup and build a proof of concept (PoC)
16that showcases the use of Measured Boot with a Discrete TPM interface.
17
18.. note::
19 The instructions given in this document are meant to build a PoC to
20 show how Measured Boot on TF-A can interact with a Discrete TPM interface.
21 This PoC is platform specific, and uses a SPI based Discrete TPM, the
22 Raspberry Pi communicates with the TPM via a GPIO pin bit-banged SPI interface.
23 For other platforms, different may be required to interface with the hardware
24 (e.g., different hardware communication protocols) and different TPM interfaces
25 (e.g., |FIFO| vs |CRB|).
26
27Components
28~~~~~~~~~~
29
30 - **Platform**: The PoC is developed on the Raspberry Pi 3 (rpi3), due to quick
31 driver development and the availability of GPIO pins to interface with a TPM
32 expansion module. Measured boot capabilities using the TCG Event Log are
33 ported to the Raspberry Pi 3 platform inside TF-A. This PoC specifically uses
34 the Raspberry Pi 3 Model B V1.2, but this PoC is compatible with other
35 Raspberry Pi 3 models.
36
37 - **Discrete TPM**: The TPM chip selected is a breakout board compatible with
38 the Raspberry Pi 3 GPIO pins. This PoC uses a |SPI| based LetsTrust TPM
39 breakout board equipped with a Infineon Optiga SLB 9670 TPM 2.0 chip. Link
40 to device: https://thepihut.com/products/letstrust-tpm-for-raspberry-pi
41
42 .. note::
43 If you have another TPM breakout board that uses the same
44 Infineon Optiga SLB 9670 TPM 2.0 SPI based chip, it will also work.
45 Ensure that the correct GPIO pins are utilized on the Raspberry Pi 3 to
46 avoid communication issues, and possible hardware failures.
47
48 - **TF-A TPM Drivers**: To interface with a physical (Discrete) TPM chip in
49 TF-A, the PoC uses TF-A drivers that provide the command, interface, link,
50 and platform layers required to send and receive data to and from the TPM.
51 The drivers are located in TFA, and not in a |SP|, so that they may be used
52 in early stages such as BL2, and in some cases, BL1. The design of the TPM
53 Drivers is documented here: :ref:`Discrete TPM drivers`.
54
55 - **U-boot BL33**: This PoC showcases measured boot up to BL33, and for
56 simplicity uses a U-boot image for BL33, so that the image is measured and
57 loaded. Currently U-boot does not have Discrete TPM support for the
58 Raspberry Pi 3 platform so the boot flow ends here.
59
60
61Building the PoC for the Raspberry Pi 3
62~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63
64**Build instructions for U-Boot.bin for Raspberry Pi 3.**
65
66First, the build requires a BL33 firmware image that can be packaged and measured
67by TF-A.
68
69U-boot can be built for the Raspberry Pi 3, but there are some changes to be made
70to allow the build to succeed. First Clone U-boot and enter the repo.
71
72.. code:: shell
73
74 git clone https://github.com/u-boot/u-boot.git
75 cd u-boot
76
77Now to switch to a specific tag ``v2024.04`` for testing purposes, and then build
78the defconfig labelled ``rpi_3_b_plus_defconfig``.
79
80.. code:: shell
81
82 git checkout tags/v2024.04 -b tfa_dtpm_poc
83 make CROSS_COMPILE=aarch64-linux-gnu- rpi_3_b_plus_defconfig
84
85Lastly open the ``.config`` and change ``CONFIG_TEXT_BASE`` and
86``CONFIG_SYS_UBOOT_START`` to ``0x11000000`` to match the BL33 starting point.
87
88.. code:: shell
89
90 vim .config
91 CONFIG_TEXT_BASE=0x11000000
92 CONFIG_SYS_UBOOT_START=0x11000000
93
94To build the u-boot binary, use the following command.
95
96.. code:: shell
97
98 make CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
99
100**Build TF-A for Raspberry Pi 3 with Discrete TPM and Measured Boot.**
101
102Copy over the ``u-boot.bin`` file over to your TF-A working directory.
103
104.. code:: shell
105
106 cp /path/to/u-boot/build/u-boot.bin /path/to/tfa/u-boot.bin
107
108TF-A build command:
109
110.. code:: shell
111
112 CROSS_COMPILE=aarch64-linux-gnu- \
113 make PLAT=rpi3 \
114 RPI3_PRELOADED_DTB_BASE=0x200000 \
115 BL33=u-boot.bin \
116 SUPPORT_VFP=1 \
117 DEBUG=0 \
118 MEASURED_BOOT=1 \
119 DISCRETE_TPM=1 \
120 MBOOT_TPM_HASH_ALG=sha256 \
121 TPM_INTERFACE=FIFO_SPI \
122 MBEDTLS_DIR=/path/to/mbedtls/repo \
123 LOG_LEVEL=40 \
124 fip all
125
126This build command is similar to the one provided in the TF-A Raspberry Pi 3
127platform port, To learn more about the platform and its build options, visit
128:ref:`Raspberry Pi 3`.
129
130 - ``RPI3_PRELOADED_DTB_BASE`` is given a different address to accommodate the
131 larger BL1 and BL2 firmware sizes, this is to accommodate the TPM drivers
132 that are packaged in BL1 and BL2 for this PoC.
133 - ``BL33`` is the non trusted firmware, in this case the U-Boot binary built
134 earlier.
135 - ``SUPPORT_VFP`` is enabled, allows Vector Floating Point operations in EL3.
136 - ``MEASURED_BOOT`` is enabled to allow the Measured Boot flow.
137 - ``DISCRETE_TPM=1`` enables the build of Discrete TPM drivers.
138 - ``MBOOT_TPM_HASH_ALG=sha256`` sets the hash algorithm to sha256, this is
139 the only algorithm supported by both TF-A Measured Boot and the SLB 9670
140 TPM 2.0.
141 - ``TPM_INTERFACE=FIFO_SPI`` specifies the use of the FIFO SPI interface.
142 - ``MBEDTLS_DIR`` is the path to your local mbedtls repo.
143 - ``LOG_LEVEL=40`` ensures that eventlog is printed at the end of BL1 and BL2.
144
145
146**Hardware Setup:**
147
148 - **TPM Connection**: Connect the LetsTrust TPM board to GPIO pins 17 - 26 on
149 the 40-pin GPIO header on the Raspberry Pi board. The 2x5 header of the TPM
150 module must be aligned to the pins in a specific orientation, match the 3v3
151 and RST pins from the TPM board to pins 17 and 18 respectively on the
152 Raspberry Pi 3 header. See `rpi3 pinout`_.
153
154 - **Serial Console**: Establish a serial connection to the Raspberry Pi 3 to
155 view serial output during the boot sequence. The GND, TXD, and RXD pins,
156 which are labelled 6, 8, and 10 on the Raspberry Pi 3 header respectively,
157 are the required pins to establish a serial connection. The recommended way
158 to connect to the board from another system is to use a USB to serial TTL
159 cable to output the serial console in a easy manner.
160
161 - **SD Card Setup**: Format a SD Card as ``FAT32`` with a default Raspbian
162 installation that is similar to the default Raspberry Pi 3 boot partition,
163 this partition will utilize the default files installed in the root
164 directory with Rasbian such as:
165
166 ::
167
168 bcm2710-rpi3-b.dtb
169 bootcode.bin
170 config.txt
171 fixup.dat
172 start.elf
173
174 Open ``config.txt`` and overwrite the file with the following lines:
175
176 ::
177
178 arm_64bit=1
179 disable_commandline_tags=2
180 enable_uart=1
181 armstub=armstub8.bin
182 device_tree_address=0x200000
183 device_tree_end=0x210000
184
185 These configurations are required to enable uart, enable 64bit mode,
186 use the build TF binary, and the modified rpi3 device tree address
187 and size.
188
189 Copy ``armstub8.bin`` from the TF-A build path to the root folder of the
190 SD card.
191
192 The SD Card is now ready to be booted.
193
194Running the PoC for the Raspberry Pi 3
195~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
196
197Insert the SD Card into the Raspberry Pi 3 SD card port and boot the system.
198
199To access the serial console output from the Raspberry Pi 3 you can either:
200
201 - Follow `instructions`_ to use PuTTY to connect to Raspberry Pi 3 serial console.
202
203 - Use the linux ``screen`` command:
204
205 .. code:: shell
206
207 screen /dev/ttyUSB0 115200
208
209Once booted the output from the serial console will look like this:
210
211.. code:: shell
212
213 Raspberry Pi Bootcode
214
215 Read File: config.txt, 153
216
217 Read File: start.elf, 2975040 (bytes)
218
219 Read File: fixup.dat, 7265 (bytes)
220
221 MESS:00:00:01.170422:0: brfs: File read: /mfs/sd/config.txt
222 MESS:00:00:01.174630:0: brfs: File read: 153 bytes
223 MESS:00:00:01.211473:0: HDMI0:EDID error reading EDID block 0 attempt 0
224 MESS:00:00:01.217639:0: HDMI0:EDID error reading EDID block 0 attempt 1
225 MESS:00:00:01.223977:0: HDMI0:EDID error reading EDID block 0 attempt 2
226 MESS:00:00:01.230313:0: HDMI0:EDID error reading EDID block 0 attempt 3
227 MESS:00:00:01.236650:0: HDMI0:EDID error reading EDID block 0 attempt 4
228 MESS:00:00:01.242987:0: HDMI0:EDID error reading EDID block 0 attempt 5
229 MESS:00:00:01.249324:0: HDMI0:EDID error reading EDID block 0 attempt 6
230 MESS:00:00:01.255660:0: HDMI0:EDID error reading EDID block 0 attempt 7
231 MESS:00:00:01.261997:0: HDMI0:EDID error reading EDID block 0 attempt 8
232 MESS:00:00:01.268334:0: HDMI0:EDID error reading EDID block 0 attempt 9
233 MESS:00:00:01.274429:0: HDMI0:EDID giving up on reading EDID block 0
234 MESS:00:00:01.282647:0: brfs: File read: /mfs/sd/config.txt
235 MESS:00:00:01.286929:0: gpioman: gpioman_get_pin_num: pin LEDS_PWR_OK not defined
236 MESS:00:00:01.487295:0: gpioman: gpioman_get_pin_num: pin DISPLAY_DSI_PORT not defined
237 MESS:00:00:01.494853:0: gpioman: gpioman_get_pin_num: pin LEDS_PWR_OK not defined
238 MESS:00:00:01.500763:0: *** Restart logging
239 MESS:00:00:01.504638:0: brfs: File read: 153 bytes
240 MESS:00:00:01.510139:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 0
241 MESS:00:00:01.517254:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 1
242 MESS:00:00:01.524112:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 2
243 MESS:00:00:01.530970:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 3
244 MESS:00:00:01.537826:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 4
245 MESS:00:00:01.544685:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 5
246 MESS:00:00:01.551543:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 6
247 MESS:00:00:01.558399:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 7
248 MESS:00:00:01.565258:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 8
249 MESS:00:00:01.572116:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 9
250 MESS:00:00:01.578730:0: hdmi: HDMI0:EDID giving up on reading EDID block 0
251 MESS:00:00:01.584634:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 0
252 MESS:00:00:01.592427:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 1
253 MESS:00:00:01.599286:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 2
254 MESS:00:00:01.606142:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 3
255 MESS:00:00:01.613001:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 4
256 MESS:00:00:01.619858:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 5
257 MESS:00:00:01.626717:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 6
258 MESS:00:00:01.633575:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 7
259 MESS:00:00:01.640431:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 8
260 MESS:00:00:01.647288:0: hdmi: HDMI0:EDID error reading EDID block 0 attempt 9
261 MESS:00:00:01.653905:0: hdmi: HDMI0:EDID giving up on reading EDID block 0
262 MESS:00:00:01.659769:0: hdmi: HDMI:hdmi_get_state is deprecated, use hdmi_get_display_state instead
263 MESS:00:00:01.668264:0: HDMI0: hdmi_pixel_encoding: 162000000
264 MESS:00:00:01.673988:0: vec: vec_middleware_power_on: vec_base: 0x7e806000 rev-id 0x00002708 @ vec: 0x7e806100 @ 0x00000420 enc: 0x7e806060 @ 0x00000220 cgmsae: 0x7e80605c @ 0x00000000
265 MESS:00:00:01.880234:0: dtb_file 'bcm2710-rpi-3-b.dtb'
266 MESS:00:00:01.889713:0: brfs: File read: /mfs/sd/bcm2710-rpi-3-b.dtb
267 MESS:00:00:01.894375:0: Loaded 'bcm2710-rpi-3-b.dtb' to 0x200000 size 0x7cb2
268 MESS:00:00:01.915761:0: brfs: File read: 31922 bytes
269 MESS:00:00:02.007202:0: brfs: File read: /mfs/sd/config.txt
270 MESS:00:00:02.017277:0: brfs: File read: 153 bytes
271 MESS:00:00:02.020772:0: Failed to open command line file 'cmdline.txt'
272 MESS:00:00:02.042302:0: gpioman: gpioman_get_pin_num: pin EMMC_ENABLE not defined
273 MESS:00:00:02.398066:0: kernel=
274 MESS:00:00:02.455255:0: brfs: File read: /mfs/sd/armstub8.bin
275 MESS:00:00:02.459284:0: Loaded 'armstub8.bin' to 0x0 size 0xdbe74
276 MESS:00:00:02.465109:0: No compatible kernel found
277 MESS:00:00:02.469610:0: Device tree loaded to 0x200000 (size 0x823f)
278 MESS:00:00:02.476805:0: uart: Set PL011 baud rate to 103448.300000 Hz
279 MESS:00:00:02.483381:0: uart: Baud rate change done...
280 MESS:00:00:02.486793:0: uart: Baud rateNOTICE: Booting Trusted Firmware
281 NOTICE: BL1: v2.11.0(release):v2.11.0-187-g0cb1ddc9c-dirty
282 NOTICE: BL1: Built : 10:57:10, Jul 9 2024
283 INFO: BL1: RAM 0x100ee000 - 0x100f9000
284 INFO: Using crypto library 'mbed TLS'
285 NOTICE: TPM Chip: vendor-id 0xd1, device-id 0x0, revision-id: 0x16
286 NOTICE: rpi3: Detected: Raspberry Pi 3 Model B (1GB, Sony, UK) [0x00a02082]
287 INFO: BL1: Loading BL2
288 INFO: Loading image id=1 at address 0x100b4000
289 INFO: Image id=1 loaded: 0x100b4000 - 0x100c0281
290 INFO: TCG_EfiSpecIDEvent:
291 INFO: PCRIndex : 0
292 INFO: EventType : 3
293 INFO: Digest : 00
294 INFO: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
295 INFO: : 00 00 00
296 INFO: EventSize : 33
297 INFO: Signature : Spec ID Event03
298 INFO: PlatformClass : 0
299 INFO: SpecVersion : 2.0.2
300 INFO: UintnSize : 1
301 INFO: NumberOfAlgorithms : 1
302 INFO: DigestSizes :
303 INFO: #0 AlgorithmId : SHA256
304 INFO: DigestSize : 32
305 INFO: VendorInfoSize : 0
306 INFO: PCR_Event2:
307 INFO: PCRIndex : 0
308 INFO: EventType : 3
309 INFO: Digests Count : 1
310 INFO: #0 AlgorithmId : SHA256
311 INFO: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
312 INFO: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
313 INFO: EventSize : 17
314 INFO: Signature : StartupLocality
315 INFO: StartupLocality : 0
316 INFO: PCR_Event2:
317 INFO: PCRIndex : 0
318 INFO: EventType : 1
319 INFO: Digests Count : 1
320 INFO: #0 AlgorithmId : SHA256
321 INFO: Digest : 55 11 51 d8 8b 7f 41 d3 18 16 f2 e8 80 bf 80 fa
322 INFO: : b4 03 6d 96 4c a0 0a 98 45 cf 25 2f 1e a9 09 3e
323 INFO: EventSize : 5
324 INFO: Event : BL_2
325 NOTICE: BL1: Booting BL2
326 INFO: Entry point address = 0x100b4000
327 INFO: SPSR = 0x3c5
328 NOTICE: BL2: v2.11.0(release):v2.11.0-187-g0cb1ddc9c-dirty
329 NOTICE: BL2: Built : 10:56:39, Jul 9 2024
330 INFO: Using crypto library 'mbed TLS'
331 NOTICE: TPM Chip: vendor-id 0xd1, device-id 0x0, revision-id: 0x16
332 INFO: BL2: Doing platform setup
333 INFO: BL2: Loading image id 3
334 INFO: Loading image id=3 at address 0x100e0000
335 INFO: Image id=3 loaded: 0x100e0000 - 0x100e706b
336 INFO: BL2: Loading image id 5
337 INFO: Loading image id=5 at address 0x11000000
338 INFO: Image id=5 loaded: 0x11000000 - 0x110a8ad8
339 INFO: TCG_EfiSpecIDEvent:
340 INFO: PCRIndex : 0
341 INFO: EventType : 3
342 INFO: Digest : 00
343 INFO: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
344 INFO: : 00 00 00
345 INFO: EventSize : 33
346 INFO: Signature : Spec ID Event03
347 INFO: PlatformClass : 0
348 INFO: SpecVersion : 2.0.2
349 INFO: UintnSize : 1
350 INFO: NumberOfAlgorithms : 1
351 INFO: DigestSizes :
352 INFO: #0 AlgorithmId : SHA256
353 INFO: DigestSize : 32
354 INFO: VendorInfoSize : 0
355 INFO: PCR_Event2:
356 INFO: PCRIndex : 0
357 INFO: EventType : 3
358 INFO: Digests Count : 1
359 INFO: #0 AlgorithmId : SHA256
360 INFO: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
361 INFO: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
362 INFO: EventSize : 17
363 INFO: Signature : StartupLocality
364 INFO: StartupLocality : 0
365 INFO: PCR_Event2:
366 INFO: PCRIndex : 0
367 INFO: EventType : 1
368 INFO: Digests Count : 1
369 INFO: #0 AlgorithmId : SHA256
370 INFO: Digest : 55 11 51 d8 8b 7f 41 d3 18 16 f2 e8 80 bf 80 fa
371 INFO: : b4 03 6d 96 4c a0 0a 98 45 cf 25 2f 1e a9 09 3e
372 INFO: EventSize : 5
373 INFO: Event : BL_2
374 INFO: PCR_Event2:
375 INFO: PCRIndex : 0
376 INFO: EventType : 1
377 INFO: Digests Count : 1
378 INFO: #0 AlgorithmId : SHA256
379 INFO: Digest : f3 00 5c ed a2 12 8b 76 b7 82 da c5 28 c3 02 52
380 INFO: : 19 e4 3a 82 f2 3c ab 1e 0d 78 84 9c b5 fe e2 4f
381 INFO: EventSize : 14
382 INFO: Event : SECURE_RT_EL3
383 INFO: PCR_Event2:
384 INFO: PCRIndex : 0
385 INFO: EventType : 1
386 INFO: Digests Count : 1
387 INFO: #0 AlgorithmId : SHA256
388 INFO: Digest : 90 28 81 42 12 b7 9b ca aa 0c 40 76 33 5a 69 71
389 INFO: : b6 19 2b 90 f2 d2 69 b8 de 8e 6d 05 4d c2 73 f9
390 INFO: EventSize : 6
391 INFO: Event : BL_33
392 NOTICE: BL1: Booting BL31
393 INFO: Entry point address = 0x100e0000
394 INFO: SPSR = 0x3cd
395 NOTICE: BL31: v2.11.0(release):v2.11.0-187-g0cb1ddc9c-dirty
396 NOTICE: BL31: Built : 10:56:58, Jul 9 2024
397 INFO: rpi3: Checking DTB...
398 INFO: rpi3: Reserved 0x10000000 - 0x10100000 in DTB
399 INFO: BL31: Initializing runtime services
400 INFO: BL31: Preparing for EL3 exit to normal world
401 INFO: Entry point address = 0x11000000
402 INFO: SPSR = 0x3c9
403
404
405 U-Boot 2024.04-g84314330-dirty (Apr 23 2024 - 15:41:54 -0500)
406
407 DRAM: 948 MiB
408 RPI 3 Model B (0xa02082)
409 Core: 68 devices, 14 uclasses, devicetree: embed
410 MMC: mmc@7e202000: 0, mmc@7e300000: 1
411 Loading Environment from FAT... OK
412 In: serial,usbkbd
413 Out: serial,vidconsole
414 Err: serial,vidconsole
415 Net: No ethernet found.
416 starting USB...
417 Bus usb@7e980000: USB DWC2
418 scanning bus usb@7e980000 for devices...
419 Error: smsc95xx_eth No valid MAC address found.
420 2 USB Device(s) found
421 scanning usb for storage devices... 0 Storage Device(s) found
422 Hit any key to stop autoboot: 2 1 0
423 Card did not respond to voltage select! : -110
424 No EFI system partition
425 No EFI system partition
426 Failed to persist EFI variables
427 No EFI system partition
428 Failed to persist EFI variables
429 No EFI system partition
430 Failed to persist EFI variables
431 Missing TPMv2 device for EFI_TCG_PROTOCOL
432 ** Booting bootflow '<NULL>' with efi_mgr
433 Loading Boot0000 'mmc 0' failed
434 EFI boot manager: Cannot load any image
435 Boot failed (err=-14)
436 Card did not respond to voltage select! : -110
437 No ethernet found.
438 No ethernet found.
439 U-Boot>
440
441
442Next steps for Discrete TPM and Measured Boot development
443~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
444
445In order to automatically validate the workings of the Discrete TPM, the creation
446of test cases that compare the eventlog image hashes with what is stored in PCR0
447are a great way to test the core functionality of the Discrete TPM in Measured Boot.
448
449Development of Discrete TPM drivers such as a reference FIFO |I2C|, MMIO, and CRB
450drivers has not started, these drivers will allow a larger number of platform
451to use a Discrete TPM in TF-A.
452
453*Copyright (c) 2025, Arm Limited. All rights reserved.*
454
455.. _TCG event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/
456.. _rpi3 pinout: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#gpio
457.. _instructions: https://www.circuitbasics.com/use-putty-to-access-the-raspberry-pi-terminal-from-a-computer/
458.. _workaround: https://github.com/mhomran/u-boot-rpi3-b-plus