-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUEFI Secure and Measured boot on DeveloperBox.html
executable file
·361 lines (296 loc) · 17.1 KB
/
UEFI Secure and Measured boot on DeveloperBox.html
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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="" />
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,400;0,700;1,400&family=Source+Sans+Pro:ital,wght@0,300;0,400;0,700;1,400&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/theme/stylesheet/style.min.css">
<link id="pygments-light-theme" rel="stylesheet" type="text/css"
href="/theme/pygments/github.min.css">
<link rel="stylesheet" type="text/css" href="/theme/font-awesome/css/fontawesome.css">
<link rel="stylesheet" type="text/css" href="/theme/font-awesome/css/brands.css">
<link rel="stylesheet" type="text/css" href="/theme/font-awesome/css/solid.css">
<meta name="author" content="Ilias Apalodimas" />
<meta name="description" content="UEFI Secure and measured Boot is the minimal basis for a trustworthy device nowdays. Let's take a look on how modern U-Boot with the help of OP-TEE can provide that without any specialized hardware." />
<meta name="keywords" content="Bootloaders, Security, U-Boot, UEFI, TPM, Measured Boot, Secure Boot">
<meta property="og:site_name" content="Volatile rumblings"/>
<meta property="og:title" content="(Cheap) UEFI Secure and Measured boot on DeveloperBox"/>
<meta property="og:description" content="UEFI Secure and measured Boot is the minimal basis for a trustworthy device nowdays. Let's take a look on how modern U-Boot with the help of OP-TEE can provide that without any specialized hardware."/>
<meta property="og:locale" content="en_US"/>
<meta property="og:url" content="/UEFI Secure and Measured boot on DeveloperBox.html"/>
<meta property="og:type" content="article"/>
<meta property="article:published_time" content="2022-01-04 20:20:00+02:00"/>
<meta property="article:modified_time" content=""/>
<meta property="article:author" content="/author/ilias-apalodimas.html">
<meta property="article:section" content="UEFI"/>
<meta property="article:tag" content="Bootloaders"/>
<meta property="article:tag" content="Security"/>
<meta property="article:tag" content="U-Boot"/>
<meta property="article:tag" content="UEFI"/>
<meta property="article:tag" content="TPM"/>
<meta property="article:tag" content="Measured Boot"/>
<meta property="article:tag" content="Secure Boot"/>
<meta property="og:image" content="site_images/profile.png">
<title>Volatile rumblings – (Cheap) UEFI Secure and Measured boot on DeveloperBox</title>
</head>
<body class="light-theme">
<aside>
<div>
<a href="">
<img src="site_images/profile.png" alt="" title="">
</a>
<h1>
<a href=""></a>
</h1>
<p>Volatile rumblings</p>
<nav>
<ul class="list">
<li>
<a target="_self" href="http://github.com/Xdp-project" >XDP</a>
</li>
</ul>
</nav>
<ul class="social">
<li>
<a class="sc-github" href="https://github.com/apalos" target="_blank">
<i class="fab fa-github"></i>
</a>
</li>
<li>
<a class="sc-linkedin" href="https://www.linkedin.com/in/ilias-apalodimas-91891a34/" target="_blank">
<i class="fab fa-linkedin"></i>
</a>
</li>
<li>
<a class="sc-twitter" href="https://www.twitter.com/_apalos" target="_blank">
<i class="fab fa-twitter"></i>
</a>
</li>
</ul>
</div>
</aside>
<main>
<nav>
<a href="">Home</a>
<a href="/archives.html">Archives</a>
<a href="/categories.html">Categories</a>
<a href="/tags.html">Tags</a>
</nav>
<article class="single">
<header>
<h1 id="UEFI Secure and Measured boot on DeveloperBox">(Cheap) UEFI Secure and Measured boot on DeveloperBox</h1>
<p>
Posted on Tue 04 January 2022 in <a href="/category/uefi.html">UEFI</a>
• 5 min read
</p>
</header>
<div>
<h6></h6>
<p><link rel="stylesheet" href="overload.css"></p>
<h2><strong>Why the DeveloperBox</strong></h2>
<p>A while ago I explained how storing EFI Variables into an RPMB partition of an
<a href="https://apalos.github.io/Protected%20UEFI%20variables%20with%20U-Boot.html#Protected%20UEFI%20variables%20with%20U-Boot">eMMC</a> works.
There's basically three requirements.</p>
<ul>
<li>Your hardware has OP-TEE support</li>
<li>A working eMMC in U-Boot and Linux</li>
<li>Upstream U-Boot support</li>
</ul>
<p>This is the only hardware I had available which abides to those requirements.
However what you'll read here applies to any hardware that has identical features.</p>
<h2><strong>Compiling (a lot)</strong></h2>
<p>There's <strong>a lot</strong> of firmware components that need to be compiled for this to work.
Just for reference you will need</p>
<ul>
<li><a href="https://github.com/ARM-software/SCP-firmware.git">SCP-firmware</a></li>
<li><a href="https://github.com/ARM-software/arm-trusted-firmware.git">TF-A</a></li>
<li><a href="https://github.com/OP-TEE/optee_os">OP-TEE</a></li>
<li><a href="https://github.com/u-boot/u-boot.git">U-Boot</a></li>
<li><a href="https://github.com/tianocore/edk2.git">EDK2</a></li>
<li><a href="https://github.com/tianocore/edk2-platforms.git">StandAloneMM from edk2-platforms</a></li>
<li><a href="https://github.com/microsoft/ms-tpm-20-ref/">fTPM</a></li>
</ul>
<p>along with complex instructions on how to compile those and assemble the image as well as some not
(yet) upstreamed patches.
Fortunately there's an OpenEmbedded layer that can do this for us on the DeveloperBox.</p>
<div class="highlight"><pre><span></span><code>git clone https://git.codelinaro.org/linaro/dependable-boot/meta-ts.git
<span class="nb">cd</span> meta-ts
kas build ci/synquacer.yml
</code></pre></div>
<h2><strong>Updating the firmware</strong></h2>
<p>You can find detailed instructions <a href="https://www.96boards.org/documentation/enterprise/developerbox/installation/board-recovery.md.html#update-using-serial-flasher">here</a>
The tl;dr version is flip DSW2-7 to enable the serial flasher, open your minicom and use xmodem to
send and update the files.</p>
<p>All the files you need will be located at <code>build/tmp/deploy/images/synquacer/</code></p>
<div class="highlight"><pre><span></span><code>flash write cm3 -> Control-A S -> send scp_romramfw_release.bin
flash write arm-tf -> Control-A S -> send fip_all_arm_tf_optee.bin
flash rawwrite 0x500000 0x100000 -> Control-A S -> send optee/tee-pager_v2.bin
flash rawwrite 0x200000 0x100000 -> Control-A S -> send u-boot.bin
</code></pre></div>
<h2><strong>Install a distro</strong></h2>
<p>I am using
<a href="https://download.fedoraproject.org/pub/fedora/linux/releases/35/Server/aarch64/iso/Fedora-Server-netinst-aarch64-35-1.2.iso">Fedora</a>
on the example here, but since the U-Boot versions since 2021.04 are
SystemReady-IR compliant any COTS distro should work.</p>
<div class="highlight"><pre><span></span><code>sudo dd <span class="k">if</span><span class="o">=</span>Fedora-Server-netinst-aarch64-35-1.2.iso <span class="nv">of</span><span class="o">=</span>/dev/sdX <span class="nv">bs</span><span class="o">=</span>128M <span class="nv">status</span><span class="o">=</span>progress
</code></pre></div>
<p>Plug in your usb stick in a port and start up the board.
In U-Boot's console do</p>
<div class="highlight"><pre><span></span><code>usb reset
load usb <span class="m">0</span> <span class="nv">$kernel_addr_r</span> efi/boot/BOOTAA64.EFI <span class="o">&&</span> bootefi <span class="nv">$kernel_addr_r</span>
</code></pre></div>
<p>Since I am using the box in headless mode, installing via VNC is a nice option to avoid
the console nuisance.</p>
<p><img src="site_images/vnc.png" alt="VNC"></p>
<p><strong>Make sure you encrypt the filesystem using a password as we'll be
needing this later on in Measured Boot</strong></p>
<p><img src="site_images/encrypt.png" alt="Encrypt FS"></p>
<p>It's worth noting that since U-Boot does not support SetVariable at runtime you'll get this error
once the installer tries to update the EFI Boot#### variables. This is far from fatal, you
can just continue the installation and fix up the boot options later.</p>
<p><img src="site_images/error.png" alt="SetVariable Error"></p>
<p>Once the installation completes reboot your board and stop U-Boot at it's console</p>
<div class="highlight"><pre><span></span><code>nvme scan
efidebug boot add -b <span class="m">0</span> Fedora nvme <span class="m">0</span> EFI/fedora/shimaa64.efi
efidebug boot order <span class="m">0</span>
bootefi bootmgr
</code></pre></div>
<p>That should set SHIM as your first boot choice.</p>
<h2>Enabling fTPM</h2>
<p>The kernel modules needed for Microsoft's <a href="https://github.com/microsoft/ms-tpm-20-ref/">fTPM</a>
are included in the Fedora35 kernel. However, since it relies on OP-TEE to
provide the RPMB access, you need to start the TEE supplicant before the module gets inserted.</p>
<h3>Compiling optee_client</h3>
<p>Get a copy of optee_client compile it and install it. The default installation will end up on
<code>/usr/local/sbin</code></p>
<div class="highlight"><pre><span></span><code>git clone https://github.com/OP-TEE/optee_client.git
<span class="nb">cd</span> optee_client <span class="o">&&</span> mkdir build <span class="o">&&</span> <span class="nb">cd</span> build
cmake ../ -DRPMB_EMU<span class="o">=</span><span class="m">0</span>
make -j<span class="k">$(</span>nproc<span class="k">)</span>
sudo make install
</code></pre></div>
<h3>Enabling fTPM on systemd</h3>
<p>Create <code>/etc/systemd/system/tee-supplicant.service</code> with the following contents</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span>Unit<span class="o">]</span>
<span class="nv">Description</span><span class="o">=</span>tee supplicant
<span class="o">[</span>Service<span class="o">]</span>
<span class="nv">User</span><span class="o">=</span>root
<span class="nv">ExecStart</span><span class="o">=</span>tee-supplicant
<span class="nv">Restart</span><span class="o">=</span>always
<span class="o">[</span>Install<span class="o">]</span>
<span class="nv">WantedBy</span><span class="o">=</span>sysinit.target
</code></pre></div>
<p>and add the service in the boot flow</p>
<div class="highlight"><pre><span></span><code>sudo systemctl <span class="nb">enable</span> tee-supplicant
</code></pre></div>
<p>If you reboot your system now your firmwareTPM should be operational.
You can check the logs with </p>
<div class="highlight"><pre><span></span><code>sudo tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements
</code></pre></div>
<h2>Automatic LUKS volume unlocking using a TPM2</h2>
<p>Remember when you installed an encrypted filesystem? With the TPM up and running now
you can automate the decryption of your root filesystem.
There's a few things missing, but hopefully those will slowly make their way up to distros.</p>
<p>PCRs are zeroed out on the platform boot and can only be reseted on a system reboot.
They can be extended by writing a SHA hash (typically SHA-1,256 for TPMv2) into
the PCR. When a PCR is extended the hardware concatenates the new hash to the
existing PCR value and new SHA is stored.</p>
<p>TPMs have the ability to seal and unseal keys tied to specific PCR values.
So you can effectively encrypt your root filesystem and store the decryption
key safely in your TPM. That key will only be released if the TPM measurements
contain the exact same values that they had when the key was sealed.</p>
<p>The PCR usage and it's purposes is described
<a href="https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf">here</a></p>
<ul>
<li><strong>PCR0:</strong> SRTM, BIOS, Host Platform Extensions, Embedded Option ROMs and PI Drivers</li>
<li><strong>PCR1:</strong> Host Platform Configuration</li>
<li><strong>PCR2:</strong> UEFI driver and application Code</li>
<li><strong>PCR3:</strong> UEFI driver and application Configuration and Data</li>
<li><strong>PCR4:</strong> UEFI Boot Manager Code (usually the MBR) and Boot Attempts</li>
<li><strong>PCR5:</strong> Boot Manager Code Configuration and Data (for use by the Boot Manager Code) and GPT/Partition Table</li>
<li><strong>PCR6:</strong> Host Platform Manufacturer Specific</li>
<li><strong>PCR7:</strong> Secure Boot Policy</li>
<li><strong>PCR8-15:</strong> Defined for use by the Static OS</li>
<li><strong>PCR16:</strong> Debug</li>
<li><strong>PCR23:</strong> Application Support</li>
</ul>
<h3>Sealing the key</h3>
<p>Fedora has clevis which can make do the sealing for you.
Make sure to install the necessary packages before you start with </p>
<div class="highlight"><pre><span></span><code>sudo dnf install clevis clevis-luks clevis-dracut clevis-udisks2 clevis-systemd
sudo clevis luks <span class="nb">bind</span> -d /dev/nvme0n1p3 tpm2 <span class="s1">'{"pcr_ids":"0,1,2,3,4,5,6,7"}'</span>
</code></pre></div>
<h3>Adding tee-supplicant to your initramfs</h3>
<p>As we mentioned the fTPM relies on the op-tee supplicant for the RPMB accesses. So the missing
piece of the puzzle in order to access your TPM, unseal your key and decrypt the
filesystem, is create an initramfs with the needed modules and the tee-supplicant.</p>
<p>Create <code>/usr/lib/dracut/modules.d/60tee-supplicant/</code> directory, copy the
<code>/etc/systemd/system/tee-supplicant.service</code> we created earlier and<br>
add a <code>module-setup.sh</code> file with the following contents.</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/bash</span>
check<span class="o">()</span> <span class="o">{</span>
require_binaries clevis-decrypt-tpm2 tpm2_createprimary tpm2_unseal tpm2_load <span class="o">||</span> <span class="k">return</span> <span class="m">1</span>
require_any_binary tpm2_pcrread tpm2_pcrlist <span class="o">||</span> <span class="k">return</span> <span class="m">1</span>
<span class="k">return</span> <span class="m">0</span>
<span class="o">}</span>
depends<span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="m">0</span>
<span class="o">}</span>
install<span class="o">()</span> <span class="o">{</span>
inst_multiple clevis-decrypt-tpm2 tpm2_createprimary tpm2_unseal tpm2_load /usr/local/sbin/tee-supplicant
inst_multiple -o tpm2_pcrread tpm2_pcrlist
inst_libdir_file <span class="s2">"libtss2-tcti-device.so*"</span>
inst <span class="s2">"</span><span class="nv">$moddir</span><span class="s2">/tee-supplicant.service"</span> <span class="s2">"</span><span class="nv">$systemdsystemunitdir</span><span class="s2">/tee-supplicant.service"</span>
<span class="nv">$SYSTEMCTL</span> -q --root <span class="s2">"</span><span class="nv">$initdir</span><span class="s2">"</span> add-wants cryptsetup.target tee-supplicant.service
<span class="o">}</span>
installkernel<span class="o">()</span> <span class="o">{</span>
<span class="nv">hostonly</span><span class="o">=</span><span class="s1">''</span> <span class="nv">instmods</span> <span class="o">=</span>drivers/char/tpm
instmods tee optee
<span class="o">}</span>
</code></pre></div>
<p>You can now re-create you initramfs with</p>
<div class="highlight"><pre><span></span><code>sudo dracut --add clevis-pin-tpm2 --add tee-supplicant --force
</code></pre></div>
<p>If everything is setup correctly you should see something along the lines of this on your screen</p>
<div class="highlight"><pre><span></span><code>Welcome to Fedora Linux <span class="m">35</span> <span class="o">(</span>Server Edition<span class="o">)</span> dracut-055-6.fc35 <span class="o">(</span>Initramfs<span class="o">)</span>!
<snip>
<span class="o">[</span> OK <span class="o">]</span> Reached target Basic System.
Starting Cryptography Setu…8ff0-43f6-9484-b4f16ff43093...
<span class="o">[</span> OK <span class="o">]</span> Started tee supplicant.
Please enter passphrase <span class="k">for</span> disk Samsung SSD <span class="m">960</span> EVO 250GB <span class="o">(</span>luks-5fe9fed9-8ff0-43f6-9484-b4f16ff43093<span class="o">)</span>:
</code></pre></div>
<p>but this time you won't have to supply a password!</p>
</div>
<div class="tag-cloud">
<p>
<a href="/tag/bootloaders.html">Bootloaders</a>
<a href="/tag/security.html">Security</a>
<a href="/tag/u-boot.html">U-Boot</a>
<a href="/tag/uefi.html">UEFI</a>
<a href="/tag/tpm.html">TPM</a>
<a href="/tag/measured-boot.html">Measured Boot</a>
<a href="/tag/secure-boot.html">Secure Boot</a>
</p>
</div>
</article>
<footer>
<p>© </p>
<p>
Built with <a href="http://getpelican.com" target="_blank">Pelican</a> using <a href="http://bit.ly/flex-pelican" target="_blank">Flex</a> theme
</p> </footer>
</main>
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "Blog",
"name": " Volatile rumblings ",
"url" : "",
"image": "site_images/profile.png",
"description": ""
}
</script>
</body>
</html>