<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Secureboot on ./concord.sh</title><link>https://concord.sh/tags/secureboot/</link><description>Recent content in Secureboot on ./concord.sh</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 08 Aug 2022 20:11:51 -0400</lastBuildDate><atom:link href="https://concord.sh/tags/secureboot/index.xml" rel="self" type="application/rss+xml"/><item><title>A Small Follow-up to UEFI Secure Boot</title><link>https://concord.sh/posts/2022/08/a-small-follow-up-to-uefi-secure-boot/</link><pubDate>Mon, 08 Aug 2022 20:11:51 -0400</pubDate><guid>https://concord.sh/posts/2022/08/a-small-follow-up-to-uefi-secure-boot/</guid><description>&lt;p>This is a follow-up post to
&lt;a href="https://concord.sh/posts/2022/08/uefi-secure-boot-the-right-way/">UEFI Secure Boot the Right Way&lt;/a>
in which I answer some questions I have received and to address some confusion
and clarify some erroneous information. Not only that, but I will share some
additional information that I found out about after publication of that post! 😃&lt;/p>
&lt;h2 id="pcr-7-and-microsofts-third-partyvendor-ca-certificate">PCR 7 and Microsoft&amp;rsquo;s Third-Party/Vendor CA Certificate&lt;/h2>
&lt;p>In my original post I expressed concern that including Microsoft&amp;rsquo;s third-party
CA could potentially downgrade security of the boot process. It turns out that
this is partially due to a misunderstanding on how PCR 7 is populated and what
actually happens when you bind some value to PCRs in the TPM.&lt;/p></description><content>&lt;p>This is a follow-up post to
&lt;a href="https://concord.sh/posts/2022/08/uefi-secure-boot-the-right-way/">UEFI Secure Boot the Right Way&lt;/a>
in which I answer some questions I have received and to address some confusion
and clarify some erroneous information. Not only that, but I will share some
additional information that I found out about after publication of that post! 😃&lt;/p>
&lt;h2 id="pcr-7-and-microsofts-third-partyvendor-ca-certificate">PCR 7 and Microsoft&amp;rsquo;s Third-Party/Vendor CA Certificate&lt;/h2>
&lt;p>In my original post I expressed concern that including Microsoft&amp;rsquo;s third-party
CA could potentially downgrade security of the boot process. It turns out that
this is partially due to a misunderstanding on how PCR 7 is populated and what
actually happens when you bind some value to PCRs in the TPM.&lt;/p>
&lt;p>As the system boots, the hashes of all executed code is measured into PCR 7.
That is, hashes of each payload are subsequently &amp;ldquo;appended&amp;rdquo; to it. The result is
that if at any point one of these payloads differs from a previous boot, (as a
result of a bootloader update, for example), then PCR 7 will differ between
those boots. When you bind a LUKS key to PCR 7, it is guaranteed that the TPM
will only reveal the key if the boot process is the same as it was when it was
sealed in the first place.&lt;/p>
&lt;p>So even if you leave Microsoft&amp;rsquo;s third-party CA certificate in the trusted
store, changing what gets executed during boot will change the value of PCR 7
and the TPM will refuse to reveal the key that was sealed. In short, my
original concerns about this are more or less moot.&lt;/p>
&lt;h2 id="microsofts-third-partyvendor-ca-certificate-may-be-required-on-some-hardware">Microsoft&amp;rsquo;s Third-Party/Vendor CA Certificate May Be Required on Some Hardware&lt;/h2>
&lt;p>This is an important piece of information I inadvertently left out. During the
hardware initialization process of booting, some devices will have option ROMs
with their own code that may need to be executed in order to initialize those
devices. The best example I can think of is NVIDIA graphics cards. More often
than not, if you install an NVIDIA GPU into your system and enable secure boot,
but neglect to install the Microsoft third-party/vendor CA certificate into the
trusted store, then the system will halt when booting because the option ROM is
not trusted by the firmware.&lt;/p>
&lt;p>I actually ran into this exact problem a few years ago with exactly the same
setup. I ended up needing to remove the GPU, disabling secure boot, then
reinstalling it and ensuring to install Microsoft&amp;rsquo;s third-party CA certificate
before enabling it again.&lt;/p>
&lt;p>&amp;hellip; Okay, I lied. I ended up RMAing the motherboard thinking I bricked it
somehow, and the vendor sent it back, unable to reproduce the problem. Only
after did I receive it did I follow the above procedure to fix the issue&amp;hellip;&lt;/p>
&lt;h2 id="can-malware-touch-secure-boot-properties-while-the-os-is-running">Can malware touch secure boot properties while the OS is running?&lt;/h2>
&lt;p>Sort of. When UEFI passes execution to the running OS, it does so by calling
the &lt;code>ExitBootServices()&lt;/code>&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> function. Part of this process involves making
most EFI variables and functions read-only or inaccessible, including protected
properties governing the operation of secure boot.&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup> Additionally, a
UEFI-compliant system&amp;rsquo;s PK (platform key) variable is made read-only as soon as
one is set. There are some other caveats around this which are far too technical
to describe here (and frankly, it&amp;rsquo;s a little too much reading even for me), but
the gist is that as long as the system firmware has implemented this process
correctly, there isn&amp;rsquo;t a concern. The secure boot variables that remain writable
within the running OS have to be authenticated, meaning that the values you put
in have to also be signed and trusted by the platform key. The only secure boot
variables with this property are the authorized device signature databases. This
is what allows things like Windows updates to add or remove trusted signatures
from the device as needed.&lt;/p>
&lt;p>So basically, as long as you trust (and/or verify!) that your motherboard is
properly UEFI-compliant, then you&amp;rsquo;re fine.&lt;/p>
&lt;h2 id="sbctl-the-secure-boot-key-manager">&lt;code>sbctl&lt;/code>, the Secure Boot Key Manager&lt;/h2>
&lt;p>Not long after the original post, I was informed about
&lt;a href="https://github.com/Foxboron/sbctl">&lt;code>sbctl&lt;/code>&lt;/a> which does most of the legwork of
the script that I had written previously. I highly recommend using it, as it
more or less completely automates the process of generating secure boot keys,
enrolling keys, and signing arbitrary EFI executables with them. It will also
take care of installing the Microsoft third-party CA certificate if needed!&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://uefi.org/specs/UEFI/2.10/07_Services_Boot_Services.html">https://uefi.org/specs/UEFI/2.10/07_Services_Boot_Services.html&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>&lt;a href="https://uefi.org/specs/UEFI/2.10/32_Secure_Boot_and_Driver_Signing.html">https://uefi.org/specs/UEFI/2.10/32_Secure_Boot_and_Driver_Signing.html&lt;/a>&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></content></item><item><title>UEFI Secure Boot the Right Way</title><link>https://concord.sh/posts/2022/08/uefi-secure-boot-the-right-way/</link><pubDate>Mon, 01 Aug 2022 17:18:34 -0400</pubDate><guid>https://concord.sh/posts/2022/08/uefi-secure-boot-the-right-way/</guid><description>&lt;p>Security around the Linux boot process is a bit of a touchy subject. In fact,
if you dig deep enough you&amp;rsquo;ll find that there are many ways to boot a Linux
system in general. There&amp;rsquo;s many different bootloaders, for example, each with
their own strengths and weaknesses. In addition, depending on the system&amp;rsquo;s or
the user&amp;rsquo;s requirements, the system may also require booting with an initramfs
or initrd. You can even boot a Linux kernel directly by taking advantage of
its &lt;code>CONFIG_EFI_STUB&lt;/code> option. While looking into the basics of securing booting
on my own machines I found that the documentation for it can sometimes be a bit
all over the place, and even then there are many guides out there that were
sometimes confusing or didn&amp;rsquo;t give the exact answers to the questions I still
had. All in all, I spent about 2 or 3 weeks really digging into it and only
afterwards did I finally come up with a solution that works well enough for me
and makes booting my various Linux machines reasonably secure.&lt;/p></description><content>&lt;p>Security around the Linux boot process is a bit of a touchy subject. In fact,
if you dig deep enough you&amp;rsquo;ll find that there are many ways to boot a Linux
system in general. There&amp;rsquo;s many different bootloaders, for example, each with
their own strengths and weaknesses. In addition, depending on the system&amp;rsquo;s or
the user&amp;rsquo;s requirements, the system may also require booting with an initramfs
or initrd. You can even boot a Linux kernel directly by taking advantage of
its &lt;code>CONFIG_EFI_STUB&lt;/code> option. While looking into the basics of securing booting
on my own machines I found that the documentation for it can sometimes be a bit
all over the place, and even then there are many guides out there that were
sometimes confusing or didn&amp;rsquo;t give the exact answers to the questions I still
had. All in all, I spent about 2 or 3 weeks really digging into it and only
afterwards did I finally come up with a solution that works well enough for me
and makes booting my various Linux machines reasonably secure.&lt;/p>
&lt;p>This post is a long-awaited one. I originally wanted to publish this a few
months ago, but systemd 251 was released which added a new feature that I
wanted to cover in addition to everything else I had compiled in. For those who
have been patiently waiting for me to finally publish this (you know who you
are), thank you.&lt;/p>
&lt;p>For the sake of brevity (even though I&amp;rsquo;ve already well-exceeded it), I will
avoid going too much into the technical details for some of the aspects and
components of the following material. I will also be skipping over some of the
alternatives and different methods of setup. The depth that I will be going into
is what I feel is relevant to gain a basic understanding of the things that you,
as a user, are setting up if you decide to do it. This is in no way intended to
be a &amp;ldquo;quick guide&amp;rdquo; or &amp;ldquo;setup for the lazy&amp;rdquo;, but that may soon follow if the
demand is high enough.&lt;/p>
&lt;h1 id="the-current-situation">The Current Situation&lt;/h1>
&lt;p>The first problem with securing the Linux boot process is that the diversity
of the many Linux distributions and how they configure the base system also
brings fragmentation around booting. This could make setting it up for yourself
difficult. Worse, most Linux distributions that do not already have UEFI secure
boot just don&amp;rsquo;t support it, and trying to set it up for yourself may result in
system instability after system upgrades. Someone who wants to proceed on such a
distribution anyway will need to ensure that they perform some extra steps after
system updates or else they may be locked out of their system on next boot or
not have a bootable system at all.&lt;/p>
&lt;p>Most Linux distributions with existing UEFI secure boot support do so by using
the GNU GRUB bootloader with a UEFI shim loader. What happens during boot is
that the system EFI firmware will execute the shim loader, which then executes
GRUB, which in turn executes the Linux kernel. The shim, when executed, will
register itself with the system EFI firmware in such a way that when the system
firmware wants to verify a signature for a to be executed EFI executable, it can
ask the shim to do so in addition to the firmware&amp;rsquo;s verification. The result is
a sort of parallel signature verification process that allows EFI executables to
have their signatures verified by both the system EFI firmware and the shim. The
primary advantage of this is that the distribution can sign their own kernels
using keys included in the shim and those signatures will be verified without
the system owner needing to load those keys into the system firmware.&lt;/p>
&lt;p>There are two problems that I (personally) have with this implementation. First,
the shim itself is signed by the Microsoft third-party key&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>. The
corresponding public key is included by default in almost all system EFI
firmwares with secure boot support, and Microsoft uses this key pair to sign
other objects. What this means is that if an attacker had another object signed
with the same key pair, they could boot it on a machine with the key loaded in
the system firmware&amp;rsquo;s trusted keys database. My understanding is that this
process is supposed to be restricted to trusted hardware vendors, but it doesn&amp;rsquo;t
seem difficult to maneuver Microsoft into signing something that could
potentially have bugs, vulnerabilities, or even backdoors of its own to
compromise other machines.&lt;/p>
&lt;p>The second problem is that a vulnerability in the GRUB bootloader could
potentially allow an attacker to bypass secure boot verification and boot a
malicious Linux kernel anyway. GRUB is no stranger to major security bugs that
could compromise secure booting, but this is unfair as a simple count of bugs
isn&amp;rsquo;t the best indicator of a project&amp;rsquo;s security track record. What is
noteworthy though, is that vulnerabilities found in GRUB are generally fixed in
bulk. This is because every time a massively critical vulnerability is found,
the Linux distributions need to get their bootloaders signed by Microsoft again
which isn&amp;rsquo;t a very timely process. Because of this, many small GRUB
vulnerabilities will go unfixed for &lt;em>months&lt;/em> until GRUB does its yearly major
release. Just this past June, a major release of GRUB was announced which fixed
multiple known security issues that have been festering for over a year&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>!&lt;/p>
&lt;p>GRUB aside, another major hurdle of Linux boot security is the initrd or
initramfs if one is in use. At boot, the kernel will also unpack an initrd
into memory which contains tools and kernel modules needed to finish booting the
system. For instance, if the root filesystem resides on a filesystem like ZFS
which is not available as a built in filesystem driver, the kernel needs to load
this kernel module from the initrd at boot in order to mount it. Another case
where this is needed is if the machine is (and it should be!) using disk
encryption. The kernel alone does not know how to decrypt the disk, let alone
ask the user for a passphrase. The initrd will contain the scripts and tools
needed to get this going. The initrd is undoubtedly a security-sensitive
object. A compromised initrd can potentially contain malicious code that can
then infect the rest of the system once it is booted. Unfortunately, current
boot security mechanisms like the aforementioned EFI shim loader in combination
with GRUB do not in any way protect the initrd from being tampered with
because there is no signature verification done against the initrd.&lt;/p>
&lt;p>At this point I think it goes without saying that for proper boot security you
really really need to have an encrypted disk. An unencrypted and unverified root
filesystem really just means that an attacker with physical access can just
modify system files in order to cause the system to load malicious code. I
didn&amp;rsquo;t feel it necessary to mention it until now because I figured having an
encrypted disk is basically standard security practice by this point and it&amp;rsquo;s
not really related specifically to UEFI secure boot. But anyway, back to secure
boot&amp;hellip;&lt;/p>
&lt;h1 id="the-solution">The Solution&lt;/h1>
&lt;p>Ultimately what needs to be done is to somehow protect every sensitive component
needed during boot from tampering. The way forward to solve all of these
problems is to take advantage of systemd&amp;rsquo;s boot stub. No, not &lt;code>systemd-boot&lt;/code>.
The boot stub.&lt;/p>
&lt;p>The systemd boot stub is a small EFI executable that does nothing by itself.
But, if you use &lt;code>objcopy&lt;/code> to build a concatenated blob containing the boot stub,
a Linux kernel which has &lt;code>CONFIG_EFI_STUB&lt;/code> enabled, the initrd, the kernel&amp;rsquo;s
commandline, and a splash image, you get a single file containing all these
components that can be signed for UEFI secure boot and executed. This resulting
file is called a unified kernel image. It&amp;rsquo;s important to note that the systemd
boot stub does not actually require systemd on the system to be used. One can
easily compile the boot stub separately from the rest of systemd and copy it
over to various systems to be used. It is not even necessary to use
&lt;code>systemd-boot&lt;/code> as the bootloader, as the resulting file with all the bits
embedded inside can be used as a standalone EFI payload that can be booted
directly from the system EFI firmware.&lt;/p>
&lt;p>What we can do is generate our own signing keys for UEFI secure boot and load
them into the system firmware&amp;rsquo;s trusted signature database. Then, we can use the
systemd boot stub to create our own unified kernel image and sign them using our
generated keys. Finally, we install our unified kernel image to the &lt;code>/boot&lt;/code>
partition and either add it as an EFI payload in the system firmware or install
&lt;code>systemd-boot&lt;/code> boot it.&lt;/p>
&lt;p>Let&amp;rsquo;s take it one step at a time, starting with&amp;hellip;&lt;/p>
&lt;h2 id="generating-secure-boot-signing-keys">Generating Secure Boot Signing Keys&lt;/h2>
&lt;p>Ideally you&amp;rsquo;d do this on a separate system that is disconnected from the network
and do all of the signing on the same machine as well. That way an attacker who
gains code or command execution on the main machine cannot simply copy the UEFI
secure boot signing keys because they would not exist on the machine. However,
if you are someone like me who tends to update their kernel or initrd fairly
frequently this can be impractical. This would mean needing to update the kernel
and initrd, then copying them to the machine for signing, sign them, then
copying them back. There is definitely some security gains here to do it this
way, but I couldn&amp;rsquo;t be bothered personally. From here on I will assume you are
working on the same machine to do the key generation and signing, but if you
would like to go the extra mile, simply do these steps on your airgapped machine
and follow the procedure I described above every time you need to re-sign your
kernel and things.&lt;/p>
&lt;p>First, there&amp;rsquo;s a few packages we will need to install. These packages contain
the tools needed to later sign our kernel images. On Gentoo, we can install
these by running:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># emerge -av efitools sbsigntools
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then, let&amp;rsquo;s create a directory on our system where we will store our keys.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># mkdir /etc/secureboot
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># chmod &lt;span style="color:#ae81ff">0700&lt;/span> /etc/secureboot
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We also set the directory&amp;rsquo;s permissions to &lt;code>0700&lt;/code> so that only the &lt;code>root&lt;/code> user
can view its contents.&lt;/p>
&lt;p>Next, let&amp;rsquo;s create the keys. There are several key pairs that need to be created
and loaded into the EFI firmware and they are all related.&lt;/p>
&lt;p>First, we will enter the directory where we will store the keys and generate a
globally unique identifier (GUID) for the machine:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># cd /etc/secureboot
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># uuidgen --random &amp;gt;guid.txt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then, we will create the platform key:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -days &lt;span style="color:#ae81ff">3650&lt;/span> -subj &lt;span style="color:#e6db74">&amp;#34;/CN=Platform Key/&amp;#34;&lt;/span> -out PK.crt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># openssl x509 -outform DER -in PK.crt -out PK.cer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># cert-to-efi-sig-list -g &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>&amp;lt;guid.txt&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> PK.crt PK.esl
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># sign-efi-sig-list -g &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>&amp;lt;guid.txt&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> -k PK.key -c PK.crt PK PK.esl PK.auth
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># sign-efi-sig-list -g &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>&amp;lt;guid.txt&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> -c PK.crt -k PK.key PK /dev/null rm_PK.auth
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The argument given to the &lt;code>/CN=&lt;/code> field denotes the canonical name that will be
filled into the generated certificate. You can put pretty much whatever you want
in this field like the hostname of the machine you are generating keys for, but
I like to keep things simple.&lt;/p>
&lt;p>The platform key is stored in the UEFI &lt;code>PK&lt;/code> variable and it controls access to
that variable as well as the &lt;code>KEK&lt;/code> variable, which is where the key exchange key
will be stored.&lt;/p>
&lt;p>The above commands will have also created a file named &lt;code>rm_PK.auth&lt;/code>. This file
can be installed to the &lt;code>PK&lt;/code> variable in order to remove the platform key in the
event that it is needed.&lt;/p>
&lt;p>Next, we need to create the key exchange key.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -days &lt;span style="color:#ae81ff">3650&lt;/span> -subj &lt;span style="color:#e6db74">&amp;#34;/CN=Key Exchange Key/&amp;#34;&lt;/span> -out KEK.crt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># openssl x509 -outform DER -in KEK.crt -out KEK.cer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># cert-to-efi-sig-list -g &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>&amp;lt;guid.txt&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> KEK.crt KEK.esl
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># sign-efi-sig-list -g &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>&amp;lt;guid.txt&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> -k PK.key -c PK.crt KEK KEK.esl KEK.auth
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The key exchange key is used to update the signature database or to sign
binaries that will be trusted by the system firmware for execution.&lt;/p>
&lt;p>Finally, we will create the signature database.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -days &lt;span style="color:#ae81ff">3650&lt;/span> -subj &lt;span style="color:#e6db74">&amp;#34;/CN=Signature Database Key/&amp;#34;&lt;/span> -out db.crt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># openssl x509 -outform DER -in db.crt -out db.cer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># cert-to-efi-sig-list -g &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>&amp;lt;guid.txt&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> db.crt db.esl
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># sign-efi-sig-list -g &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>&amp;lt;guid.txt&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> -k KEK.key -c KEK.crt db db.esl db.auth
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The signature database is stored in the system&amp;rsquo;s &lt;code>db&lt;/code> variable and is what is
used to validate signed EFI binaries and other payloads when secure boot is
enabled.&lt;/p>
&lt;h2 id="installing-keys-and-signing-things">Installing Keys and Signing Things&lt;/h2>
&lt;p>Now that our keys are created, we can start signing objects with them. The way
to do this is via the &lt;code>sbsign&lt;/code> utility:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># sbsign &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --key /etc/secureboot/db.key \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --cert /etc/secureboot/db.crt \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --output /boot/EFI/systemd/systemd-bootx64.efi \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> /boot/EFI/systemd/systemd-bootx64.efi
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above command will sign the systemd-boot bootloader and overwrite the
original file. If you wish to preserve the original, unsigned file, simply point
the &lt;code>--output&lt;/code> argument to a different location.&lt;/p>
&lt;p>In order to actually take advantage of signature verification, though, we need
to install our keys into the EFI firmware. We can do this from the running
operating system using the &lt;code>efi-updatevar&lt;/code> utility:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># efi-updatevar -f /etc/secureboot/PK.auth PK
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># efi-updatevar -f /etc/secureboot/KEK.auth KEK
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span># efi-updatevar -f /etc/secureboot/db.auth db
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If this is not an option, or you&amp;rsquo;d like to do this manually, you can instead
copy the &lt;code>*.auth&lt;/code> files to the &lt;code>/boot&lt;/code> directory or some other device that we
can read from the system firmware (usually an external FAT partition). Then,
from within the EFI firmware settings we can manually load the keys. Finally, we
can enable secure boot from within the firmware.&lt;/p>
&lt;style type="text/css">.notice{--root-color:#444;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#c33;--warning-content:#fee;--info-title:#fb7;--info-content:#fec;--note-title:#6be;--note-content:#e7f2fa;--tip-title:#5a5;--tip-content:#efe}@media (prefers-color-scheme:dark){.notice{--root-color:#ddd;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#800;--warning-content:#400;--info-title:#a50;--info-content:#420;--note-title:#069;--note-content:#023;--tip-title:#363;--tip-content:#121}}body.dark .notice{--root-color:#ddd;--root-background:#eff;--title-color:#fff;--title-background:#7bd;--warning-title:#800;--warning-content:#400;--info-title:#a50;--info-content:#420;--note-title:#069;--note-content:#023;--tip-title:#363;--tip-content:#121}.notice{padding:18px;line-height:24px;margin-bottom:24px;border-radius:4px;color:var(--root-color);background:var(--root-background)}.notice p:last-child{margin-bottom:0}.notice-title{margin:-18px -18px 12px;padding:4px 18px;border-radius:4px 4px 0 0;font-weight:700;color:var(--title-color);background:var(--title-background)}.notice.warning .notice-title{background:var(--warning-title)}.notice.warning{background:var(--warning-content)}.notice.info .notice-title{background:var(--info-title)}.notice.info{background:var(--info-content)}.notice.note .notice-title{background:var(--note-title)}.notice.note{background:var(--note-content)}.notice.tip .notice-title{background:var(--tip-title)}.notice.tip{background:var(--tip-content)}.icon-notice{display:inline-flex;align-self:center;margin-right:8px}.icon-notice img,.icon-notice svg{height:1em;width:1em;fill:currentColor}.icon-notice img,.icon-notice.baseline svg{top:.125em;position:relative}&lt;/style>
&lt;div>&lt;svg width="0" height="0" display="none" xmlns="http://www.w3.org/2000/svg">&lt;symbol id="tip-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">&lt;path d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"/>&lt;/symbol>&lt;symbol id="note-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">&lt;path d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/>&lt;/symbol>&lt;symbol id="warning-notice" viewBox="0 0 576 512" preserveAspectRatio="xMidYMid meet">&lt;path d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"/>&lt;/symbol>&lt;symbol id="info-notice" viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet">&lt;path d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"/>&lt;/symbol>&lt;/svg>&lt;/div>&lt;div class="notice warning" >
&lt;p class="first notice-title">&lt;span class="icon-notice baseline">&lt;svg>&lt;use href="#warning-notice">&lt;/use>&lt;/svg>&lt;/span>Warning&lt;/p>&lt;p>If you are using a bootloader such as &lt;code>systemd-boot&lt;/code>, you will need to ensure to
sign the bootloader itself or your system won&amp;rsquo;t boot!&lt;/p>&lt;/div>
&lt;p>Either way you do this, you should ensure that you protect the firmware
settings from modification. On most motherboards this is generally just an
administrator password and admittedly could be better, but unfortunately this is
what we are stuck with. The reason you should do this is that an attacker with
physical access could simply wipe the secure boot keys or simply turn secure
boot off in order to trick the system into booting into an insecure state.&lt;/p>
&lt;h2 id="putting-it-all-together">Putting It All Together&lt;/h2>
&lt;p>Before any of what we are about to do can work, your kernel must have
&lt;code>CONFIG_EFI_STUB&lt;/code> enabled. This is needed to allow the system firmware (or
systemd&amp;rsquo;s boot stub) to pass execution directly to the kernel.&lt;/p>
&lt;p>To ensure that the initrd is protected from tampering as well as the kernel
image, we&amp;rsquo;ll need to combine the initrd and kernel into a single object for
signing. As mentioned earlier, the systemd boot stub is a small EFI executable
that can be combined with a Linux kernel, an initrd, the kernel commandline, and
a splash image in order to generate a single file that can be signed for secure
boot. For this we use &lt;code>objcopy&lt;/code> to combine the required components:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># objcopy --add-section .osrel&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;/etc/os-release&amp;#34;&lt;/span> &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --change-section-vma .osrel=0x20000 \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .cmdline=&amp;#34;/etc/kernel/cmdline&amp;#34; \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .cmdline=0x30000 \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .splash=&amp;#34;/etc/kernel/splash.bmp&amp;#34; \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .splash=0x40000 \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .linux=&amp;#34;/boot/vmlinuz-5.15.58-gentoo&amp;#34; \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .linux=0x2000000 \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .initrd=&amp;#34;/boot/initramfs-5.15.58-gentoo&amp;#34; \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .initrd=0x4000000 \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;/usr/lib/systemd/boot/efi/linuxx64.efi.stub&amp;#34; \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;#34;/boot/EFI/Linux/linux-5.15.58-gentoo.efi&amp;#34;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>There&amp;rsquo;s a lot to unpack here in this command, but let&amp;rsquo;s go through it piece by
piece:&lt;/p>
&lt;p>We embed various components into the resulting file. These are:&lt;/p>
&lt;ul>
&lt;li>&lt;code>/etc/os-release&lt;/code> - the OS release information file&lt;/li>
&lt;li>&lt;code>/etc/kernel/cmdline&lt;/code> - a plain text file containing the kernel commandline&lt;/li>
&lt;li>&lt;code>/etc/kernel/splash.bmp&lt;/code> - a splash image in BMP format&lt;/li>
&lt;li>&lt;code>/boot/vmlinuz-5.15.58-gentoo&lt;/code> - the kernel image&lt;/li>
&lt;li>&lt;code>/boot/initramfs-5.5.15-gentoo&lt;/code> - the initrd&lt;/li>
&lt;/ul>
&lt;p>It should be noted that on Gentoo, the &lt;code>VERSION_ID&lt;/code> field in &lt;code>/etc/os-release&lt;/code>
may not exist. This field is read by &lt;code>systemd-boot&lt;/code> when populating the list of
valid bootable entries. This is not needed if you intend to boot the image
directly from firmware, but if you are using &lt;code>systemd-boot&lt;/code> you will need this
field. I have mine set to &lt;code>&amp;quot;2.8&amp;quot;&lt;/code>.&lt;/p>
&lt;p>Each argument which adds a file is separated by an argument which sets the
offset for the file to be inserted. I suggest not to change these as I&amp;rsquo;m pretty
sure they may be hard-coded but don&amp;rsquo;t quote me on that.&lt;/p>
&lt;p>Finally, near the end of the command we see the path to the systemd boot stub
and the output path to the resulting file.&lt;/p>
&lt;p>For convenience, what I have done on my systems is install the &lt;code>systemd-boot&lt;/code>
&lt;code>installkernel&lt;/code> script (&lt;code>installkernel-systemd-boot&lt;/code> on Gentoo) along with a
kernel install script hook I wrote that automates this process whenever I
rebuild the kernel:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/usr/bin/env bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>set -Eeuo pipefail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>COMMAND&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>1&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>KERNEL_VERSION&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>2&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BOOT_DIR_ABS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>3&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>KERNEL_IMAGE&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>4-&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># If KERNEL_INSTALL_MACHINE_ID is defined but empty, BOOT_DIR_ABS is a fake directory.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># So, let&amp;#39;s skip creating a unified kernel image.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> ! &lt;span style="color:#f92672">[[&lt;/span> &lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_MACHINE_ID-x&lt;span style="color:#e6db74">}&lt;/span> &lt;span style="color:#f92672">]]&lt;/span>; &lt;span style="color:#66d9ef">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#f92672">[[&lt;/span> -d &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">]]&lt;/span>; &lt;span style="color:#66d9ef">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> INITRD&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;initrd&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> TARGET&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;../../EFI/Linux/linux-&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_VERSION&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">.efi&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">else&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> BOOT_DIR_ABS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;/boot&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> INITRD&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;initramfs-&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_VERSION&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">.img&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> TARGET&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;linux-&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_VERSION&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">.efi&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>die&lt;span style="color:#f92672">()&lt;/span> &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>1&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">case&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>COMMAND&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> add&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[[&lt;/span> -f &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>/../etc/secureboot/db.key &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> -f &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>/../etc/secureboot/db.cer &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#f92672">||&lt;/span> die &lt;span style="color:#e6db74">&amp;#34;No valid keys found in /etc/secureboot!&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[[&lt;/span> -f &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>/../etc/kernel/cmdline &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#f92672">||&lt;/span> die &lt;span style="color:#e6db74">&amp;#34;Cannot proceed: No such file &amp;#39;/etc/kernel/cmdline&amp;#39;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">[[&lt;/span> -f &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>/../etc/os-release &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#f92672">||&lt;/span> die &lt;span style="color:#e6db74">&amp;#34;Cannot proceed: No such file &amp;#39;/etc/kernel/splash.bmp&amp;#39;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> args&lt;span style="color:#f92672">=(&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .osrel&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/../etc/os-release&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .osrel&lt;span style="color:#f92672">=&lt;/span>0x20000
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .cmdline&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/../etc/kernel/cmdline&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .cmdline&lt;span style="color:#f92672">=&lt;/span>0x30000
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .splash&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/../etc/kernel/splash.bmp&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .splash&lt;span style="color:#f92672">=&lt;/span>0x40000
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .linux&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/linux&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .linux&lt;span style="color:#f92672">=&lt;/span>0x2000000
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#f92672">[[&lt;/span> -f &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>INITRD&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">]]&lt;/span>; &lt;span style="color:#66d9ef">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Using initrd &lt;/span>&lt;span style="color:#e6db74">${&lt;/span>INITRD&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> args&lt;span style="color:#f92672">+=(&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --add-section .initrd&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>INITRD&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --change-section-vma .initrd&lt;span style="color:#f92672">=&lt;/span>0x4000000
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> args&lt;span style="color:#f92672">+=(&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/../usr/lib/systemd/boot/efi/linuxx64.efi.stub&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>TARGET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Creating unified kernel image...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> objcopy &lt;span style="color:#e6db74">${&lt;/span>args[@]&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Signing the unified kernel image...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sbsign &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --key &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>/../etc/secureboot/db.key &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --cert &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_BOOT_ROOT&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>/../etc/secureboot/db.crt &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --output &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>TARGET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>TARGET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;Removing old loader entry...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> rm -vf &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/../../loader/entries/&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_INSTALL_MACHINE_ID&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">-&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>KERNEL_VERSION&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">.conf&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> remove&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> rm -f -- &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BOOT_DIR_ABS&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>TARGET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">esac&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above script, when installed with executable permissions to
&lt;code>/etc/kernel/install.d/99-secureboot.install&lt;/code>, take care of combining all these
files together and installing them to the proper location.&lt;/p>
&lt;h2 id="going-a-step-further">Going a Step Further&lt;/h2>
&lt;p>&lt;code>systemd-cryptenroll&lt;/code> is a utility that enrolls new key slots into an existing
LUKS device. These new key slots can be handled by the &lt;code>systemd-cryptsetup&lt;/code>
tool such that the user can be prompted to decrypt the device. The advantage
of these two tools in tandem is that we can enroll key slots that require the
user to do more than just enter a passphrase to unlock the device.
&lt;code>systemd-cryptenroll&lt;/code> has support for PKCS#11-compliant security tokens, FIDO2
tokens, and TPM2 devices. The latter is what we will be focusing on here.&lt;/p>
&lt;p>At a high level we can take advantage of a TPM2 device on the system to seal the
key to decrypt the root filesystem at boot, then have &lt;code>systemd-cryptsetup&lt;/code> ask
us for a passphrase in order to ask the TPM to unseal the key. Why ask the TPM
to unseal the key? Well, this is because when we seal a key or some other secret
data in the TPM, the TPM will only unseal it if the platform configuration
registers (PCRs) match. What happens during boot is the TPM will have stored
hashes of each of the different components that were used during bootup, and if
we seal a secret in the TPM against these hashes, the TPM will only unseal the
secret if they match. What this means for us is that we can seal the disk
decryption key in the TPM against one or more TPM2 PCRs, and the system has to
be in a trusted state during boot in order for the disk to be decrypted. For me
this means that the TPM will only hand over the disk decryption key if secure
boot is enabled and all the signatures of the different payloads during boot
were successfully verified.&lt;/p>
&lt;p>&lt;code>systemd-cryptenroll&lt;/code> allows us to either add a key slot that requires a
passphrase or add a key slot that does not. The latter will allow the system to
boot without a passphrase so long the PCRs match. This is convenient in that we
can be sure that the system is in a secure state when it boots, but the risk is
that if the machine does something after booting is finished that could
potentially be compromised or used to leverage access, an attacker can do so.
A prime example of this is this lovely penetration test conducted by Dolos
Group&lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup>. What they found was that even though the machine they were trying to
use for attack was properly configured for secure boot, the machine would
automatically connect to the company&amp;rsquo;s internal network via an automatic VPN
connection that was established after boot. They were able to leverage this in
order to gain a foothold in the internal network even though the machine itself
was sufficiently secured. The solution? Require a PIN or passphrase to continue
booting even though the device was booted in a secure state. The takeaway is
that any potential attack surface that exists on the machine after boot cannot
be used if the attacker does not know the PIN or passphrase to complete the boot
process.&lt;/p>
&lt;p>To ensure that &lt;code>systemd-cryptenroll&lt;/code> can detect the TPM2 device, we can use:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># systemd-cryptenroll --tpm2-device&lt;span style="color:#f92672">=&lt;/span>list
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PATH DEVICE DRIVER
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/dev/tpmrm0 IFX0785:00 tpm_tis
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This will print the path to the TPM device in &lt;code>/dev&lt;/code> as well as information
about it if it is found. If you do not see a device here, make sure you actually
have a TPM2 device installed and that the kernel can load the appropriate driver
for it.&lt;/p>
&lt;p>Since we have only one TPM2 device on this system, it is safe to use
&lt;code>--tpm2-device=auto&lt;/code> when issuing commands that will work on the TPM. Otherwise,
we would need to specify the path to the TPM2 device in this argument. To enroll
a new key slot using TPM2 PCR 7, which is the PCR that stores the secure boot
state, we can use:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># systemd-cryptenroll --tpm2-device&lt;span style="color:#f92672">=&lt;/span>auto --tpm2-pcrs&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">7&lt;/span> /dev/nvme0n1p2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This command will ask for the current passphrase to unlock the &lt;code>/dev/nvme0n1p2&lt;/code>
LUKS partition and then enroll a new key slot against PCR 7 into it. At boot,
this partition will automatically be decrypted at boot as long as PCR 7 matches.
If, instead, we want to also enter a PIN or passphrase to unlock it in addition
to being in a secure boot state, we can use:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># systemd-cryptenroll --tpm2-device&lt;span style="color:#f92672">=&lt;/span>auto --tpm2-pcrs&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">7&lt;/span> --tpm2-with-pin&lt;span style="color:#f92672">=&lt;/span>true /dev/nvme0n1p2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This command is the same as the above except we add &lt;code>--tpm2-with-pin=true&lt;/code> which
tells &lt;code>systemd-cryptenroll&lt;/code> to enroll a key slot that requires both PCR 7 hashes
to match as well as for the user to enter a PIN or passphrase. When we enter
this command, it will again ask us to enter the current passphrase to unlock
&lt;code>/dev/nvme0n1p2&lt;/code> and then ask for a PIN to use for unlocking via the TPM.
Although it says PIN for this prompt (and even when unlocking), non-numeric
characters are allowed.&lt;/p>
&lt;p>We can also use other PCRs available in the TPM other than just PCR 7. The
&lt;code>systemd-cryptenroll&lt;/code> man page&lt;sup id="fnref:4">&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref">4&lt;/a>&lt;/sup> has a table of well-known PCRs and their
contents. For example, PCR 0 will contain a measurement of the core system
firmware executable code. So, if you wanted to ensure that the system firmware
itself was not updated or modified since enrolling, you can include it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span># systemd-cryptenroll --tpm2-device&lt;span style="color:#f92672">=&lt;/span>auto --tpm2-pcrs&lt;span style="color:#f92672">=&lt;/span>0,7 --tpm2-with-pin&lt;span style="color:#f92672">=&lt;/span>true /dev/nvme0n1p2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This gives an extra layer of defense in verifying that not only secure boot is
in a known good state, but also checking other components. Keep in mind that by
enabling the use of other PCRs, updating any of these components (even
legitimately) will stop the TPM from unsealing secrets sealed against these
PCRs. Windows&amp;rsquo;s BitLocker for example only uses PCR 7&lt;sup id="fnref:5">&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref">5&lt;/a>&lt;/sup>, specifically to avoid
boot issues when the system owner updates the system firmware.&lt;/p>
&lt;p>At this point the next best thing to do would be to enroll a recovery key to the
partition using the &lt;code>--recovery-key&lt;/code> argument to &lt;code>systemd-cryptenroll&lt;/code> and then
securely storing it somewhere and wiping the original passphrase slot. This
would ensure that the LUKS partition can only be unlocked by using a
PIN/passphrase in conjunction with being in a secure boot state. The downside of
this is that if something were to ever go wrong with the boot process, you would
likely be locked out of the system until you have access to the recovery key.&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://techcommunity.microsoft.com/t5/hardware-dev-center/updated-uefi-signing-requirements/ba-p/1062916">https://techcommunity.microsoft.com/t5/hardware-dev-center/updated-uefi-signing-requirements/ba-p/1062916&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>&lt;a href="https://www.openwall.com/lists/oss-security/2022/06/07/5">https://www.openwall.com/lists/oss-security/2022/06/07/5&lt;/a>&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>&lt;a href="https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network">https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network&lt;/a>&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:4">
&lt;p>&lt;a href="https://www.freedesktop.org/software/systemd/man/systemd-cryptenroll.html#--tpm2-pcrs=PCR">https://www.freedesktop.org/software/systemd/man/systemd-cryptenroll.html#--tpm2-pcrs=PCR&lt;/a>&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:5">
&lt;p>&lt;a href="https://docs.microsoft.com/en-us/windows/security/information-protection/bitlocker/bitlocker-group-policy-settings#about-the-platform-configuration-register-pcr">https://docs.microsoft.com/en-us/windows/security/information-protection/bitlocker/bitlocker-group-policy-settings#about-the-platform-configuration-register-pcr&lt;/a>&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></content></item></channel></rss>