Merge pull request #28891 from poettering/pcrlock

new pcrlock tool for generating signed PCR policies for PCR 0, 1, 4, …
This commit is contained in:
Luca Boccassi
2023-11-03 16:07:43 +00:00
committed by GitHub
54 changed files with 8548 additions and 118 deletions

95
TODO
View File

@@ -147,6 +147,23 @@ Features:
root=nvme:<trtype>:<traddr>:<trsvcid>:<nqn>:<partition> to boot directly from
nvme-oF
* pcrlock:
- make signed PCR work together with pcrlock
- add kernel-install plugin that automatically creates UKI .pcrlock file when
UKI is installed, and removes it when it is removed again
- automatically install PE measurement of sd-boot on "bootctl install"
- write generated pcrlock signature files to the ESP as credential, one for
each installed OS & pick up generated pcrlock signature file in sd-stub,
pass it via initrd to OS
- pre-calc sysext + kernel cmdline measurements
- pre-calc cryptsetup root key measurement
- maybe make systemd-repart generate .pcrlock for old and new GPT header in
/run?
- Add support for more than 8 branches per PCR OR
- add "systemd-pcrlock lock-kernel-current" or so which synthesizes .pcrlock
policy from currently booted kernel/event log, to close gap for first boot
for pre-built images
* add a new systemd-project@.service that is very similar to user@.service but
uses DynamicUser=1 and no PAMName= to invoke an unprivileged somewhat
light-weight service manager. Use HOME=/var/lib/systemd/projects/%i as home
@@ -299,54 +316,6 @@ Features:
* systemd-mount should only consider modern file systems when mounting, similar
to systemd-dissect
* new "systemd-pcrlock" component for dealing with PCR4. Design idea:
1. define /{etc,usr,var/lib}/pcrlock.d/<component>/<version>.pcrlock
2. these files contain list of hashes that will be measured when component is
run, per PCR
3. each component involved in the boot that is deterministically measured can
place one or more of these files in those dirs (shim, sd-boot,
sd-stub/UKI, cryptsetup, pcrphase, pcrfs, …)
4. since each component has its own dir, with multiple files in them, package
such as kernels (of which there can be multiple installed at the same
time) can be grouped together: only one of them is measured at a time.
5. whenever a new component is added or an old one removed, or the PCR lock
shall be relaxed or tightened the systemd-pcrlock tool is invoked.
6. tool iterates through all these files, orders them alphabetically by
component, then matches them up with current measurements (as per uefi
event log), identifying by hash, accepting that the "beginning" of the
measurements might not be recognizable.
7. Then calculates expected PCR values starting with the "unrecognized
head" from the event log, then continuing with all of components
defined via the .pcrlock files (but dropping out the "recognized tail"
from the uefi event log). (This might mean combinatorial explosion, if
there are multiple shims, multiple sd-boot, and so on.)
8. Generates a public/private key pair on the TPM
9. Generates a counter object in the TPM, with a policy that allows only
one-by-one increase with signature policy by the public/private key pair.
10. now signs policies of all expected PCR values with the generated keypair,
using all combinations of components defined in the .pcrlock files
restricting it to the counter + 1.
11. locks down the keypair with a signed policy with its own public key
12. generates JSON file of all these policies with their signatures, drops
them as singleton in ESP
13. increases the counter by one.
14. after boot sd-stub picks JSON up from ESP, passes it to userspace via
.extra
15. JSON contained policies can now be used to unlock disk as well as the
public/key itself for signing further policies, as well as increment for
the counter
16. whenever any of the components above is added/removed new JSON file with
signatures for counter + 1 is generated, dropped in ESP, then counter
increased. (i.e. this means the "recognized tail" of the event log is
deterministically swapped out)
17. when firmware update is expected, relaxed signed policy is generated for
next boot only valid if counter is increased (this means the
"unrecognized head" for the event log can change without losing access)
18. on every boot checks if releaxed policy is in effect, if so, new strict
policy is generated and counter increased.
Net result: Removes downgrade attack surface + Locks OS to firmware + Allows
downgrades within bounds
* add another PE section ".fname" or so that encodes the intended filename for
PE file, and validate that when loading add-ons and similar before using
it. This is particularly relevant when we load multiple add-ons and want to
@@ -469,30 +438,6 @@ Features:
* SIGRTMIN+18 and memory pressure handling should still be added to: hostnamed,
localed, oomd, timedated.
* in order to make binding to PCR 4 realistic:
- generate one keypair "U" and store it in a tpm2 nvindex.
- Generate another keypair "P" and store it in a second tpm2 nvindex.
- allocate a persistent counter object "C" in the tpm2
- Enroll all user objects (i.e. luks volumes, creds, …) to a tpm2 policy
signed by U.
- Lock both U and P down with a tpm2 policy signed by P (yes, P can only be
used if a signature by P itself can be provided)
- For regular reboots generate a signature for a restrictive PCR4 + counter C
based policy with key P. Place signature in EFI var, so it can be found on
next boot
- For reboots where a firmware update is expected generate a signature with a
more open policy against just counter C. Place signature in same EFI var.
- Increase C whenever switching between these two signature types.
- During early boot, use the signature from the EFI var to unlock U and P.
Use it to generate a signature for unlocking user objects given the current
PCR 4 value, store that away into /run somewhere, for user during the whole
later boot.
- When booting up automatically update the mentioned efi var so that it
contains the restrictive signature. But also generate a signature ahead of
time that could be used in case during the current boot we later detect we might
need to reboot for a firmware update. Store that in /run somewhere, so that
it can be placed in the EFI var, if needed.
* repart/gpt-auto/DDIs: maybe introduce a concept of "extension" partitions,
that have a new type uuid and can "extend" earlier partitions, to work around
the fact that systemd-repart can only grow the last partition defined. During
@@ -1027,12 +972,6 @@ Features:
set up the directory so that it can only be accessed if host and app are in
order.
* TPM2: extend unlock policy to protect against version downgrades in signed
policies: policy probably must take some nvram based generation counter into
account that can only monotonically increase and can be used to invalidate
old PCR signatures. Otherwise people could downgrade to old signed PCR sets
whenever they want.
* update HACKING.md to suggest developing systemd with the ideas from:
https://0pointer.net/blog/testing-my-system-code-in-usr-without-modifying-usr.html
https://0pointer.net/blog/running-an-container-off-the-host-usr.html

View File

@@ -808,6 +808,22 @@
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
</varlistentry>
<varlistentry>
<term><option>tpm2-pcrlock=</option></term>
<listitem><para>Takes an absolute path to a TPM2 pcrlock policy file, as produced by the
<citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry>
tool. This permits locking LUKS2 volumes to a local policy of allowed PCR values with
variants. See
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
for details on enrolling TPM2 pcrlock policies. If this option is not specified but it is attempted
to unlock a LUKS2 volume with a TPM2 pcrlock enrollment a suitable signature file
<filename>pcrlock.json</filename> is searched for in <filename>/run/systemd/</filename> and
<filename>/var/lib/systemd/</filename> (in this order).</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><option>tpm2-measure-pcr=</option></term>

View File

@@ -1004,6 +1004,16 @@ manpages = [
['systemd-nspawn', '1', [], ''],
['systemd-oomd.service', '8', ['systemd-oomd'], 'ENABLE_OOMD'],
['systemd-path', '1', [], ''],
['systemd-pcrlock',
'8',
['systemd-pcrlock-file-system.service',
'systemd-pcrlock-firmware-code.service',
'systemd-pcrlock-firmware-config.service',
'systemd-pcrlock-machine-id.service',
'systemd-pcrlock-make-policy.service',
'systemd-pcrlock-secureboot-authority.service',
'systemd-pcrlock-secureboot-policy.service'],
'ENABLE_BOOTLOADER'],
['systemd-pcrphase.service',
'8',
['systemd-pcrextend',
@@ -1139,6 +1149,7 @@ manpages = [
['systemd.nspawn', '5', [], ''],
['systemd.offline-updates', '7', [], ''],
['systemd.path', '5', [], ''],
['systemd.pcrlock', '5', ['systemd.pcrlock.d'], ''],
['systemd.preset', '5', [], ''],
['systemd.resource-control', '5', [], ''],
['systemd.scope', '5', [], ''],

View File

@@ -519,6 +519,20 @@
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--tpm2-pcrlock=</option><arg>PATH</arg></term>
<listitem><para>Configures a TPM2 pcrlock policy to bind encryption to. Expects a path to a pcrlock
policy file as generated by the
<citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry>
tool. If a TPM2 device is enrolled and this option is not used but a file
<filename>pcrlock.json</filename> is found in <filename>/run/systemd/</filename> or
<filename>/var/lib/systemd/</filename> it is automatically used. Assign an empty string to turn this
behaviour off.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--wipe-slot=</option><arg rep="repeat">SLOT</arg></term>

559
man/systemd-pcrlock.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -388,6 +388,16 @@
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--tpm2-pcrlock=</option><arg>PATH</arg></term>
<listitem><para>Configures a TPM2 pcrlock policy to bind encryption to. See
<citerefentry><refentrytitle>systemd-cryptenroll</refentrytitle><manvolnum>1</manvolnum></citerefentry>
for details on this option.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--split=</option><arg>BOOL</arg></term>

298
man/systemd.pcrlock.xml Normal file
View File

@@ -0,0 +1,298 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<refentry id="systemd.pcrlock"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>systemd.pcrlock</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>systemd.pcrlock</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>systemd.pcrlock</refname>
<refname>systemd.pcrlock.d</refname>
<refpurpose>PCR measurement prediction files</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><literallayout>
<filename>/etc/pcrlock.d/*.pcrlock</filename>
<filename>/etc/pcrlock.d/*.pcrlock.d/*.pcrlock</filename>
<filename>/run/pcrlock.d/*.pcrlock</filename>
<filename>/run/pcrlock.d/*.pcrlock.d/*.pcrlock</filename>
<filename>/var/lib/pcrlock.d/*.pcrlock</filename>
<filename>/var/lib/pcrlock.d/*.pcrlock.d/*.pcrlock</filename>
<filename>/usr/local/pcrlock.d/*.pcrlock</filename>
<filename>/usr/local/pcrlock.d/*.pcrlock.d/*.pcrlock</filename>
<filename>/usr/lib/pcrlock.d/*.pcrlock</filename>
<filename>/usr/lib/pcrlock.d/*.pcrlock.d/*.pcrlock</filename></literallayout></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><filename>*.pcrlock</filename> files define expected TPM2 PCR measurements of components involved
in the boot
process. <citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry>
uses such pcrlock files to analyze and predict TPM2 PCR measurements. The pcrlock files are JSON arrays
that follow a subset of the <ulink
url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Common Event Log Format
(CEL-JSON)</ulink> specification. Specifically the <literal>recnum</literal>, <literal>content</literal>,
and <literal>content_type</literal> record fields are not used and ignored if present. Each pcrlock file
defines one set of expected, ordered PCR measurements of a specific component of the boot.</para>
<para>*.pcrlock files may be placed in various <filename>.d/</filename> drop-in directores (see above for
a full list). All matching files discovered in these directories are sorted alphabetically by their file
name (without taking the actual directory they were found in into account): pcrlock files with
alphabetically earlier names are expected to cover measurements done before those with alphabetically
later names. In order to make positioning pcrlock files in the boot process convenient the files are
expected (by convention, this is not enforced) to be named
<literal><replaceable>NNN</replaceable>-<replaceable>component</replaceable>.pcrlock</literal> (where
<replaceable>NNN</replaceable> is a three-digit decimal number), for example
<filename>750-enter-initrd.pcrlock</filename>.</para>
<para>For various components of the boot process more than one alternative pcrlock file shall be
supported (i.e. "variants"). For example to cover multiple kernels installed in parallel in the access
policy, or multiple versions of the boot loader. This can be done by placing
<filename>*.pcrlock.d/*.pcrlock</filename> in the drop-in dirs, i.e. a common directory for a specific
component, that contains one or more pcrlock files each covering one <emphasis>variant</emphasis> of the
component. Example: <filename>650-kernel.pcrlock.d/6.5.5-200.fc38.x86_64.pcrlock</filename> and
<filename>650-kernel.pcrlock.d/6.5.7-100.fc38.x86_64.pcrlock</filename></para>
<para>Use <command>systemd-pcrlock list-components</command> to list all pcrlock files currently
installed.</para>
<para>Use the various <command>lock-*</command> commands of <command>systemd-pcrlock</command> to
automatically generate suitable pcrlock files for various types of resources.</para>
</refsect1>
<refsect1>
<title>Well-known Components</title>
<para>Components of the boot process may be defined freely by the administrator or OS vendor. The
following components are well-known however, and are defined by systemd. The list below is useful for
ordering local pcrlock files properly against these components of the boot.</para>
<variablelist>
<varlistentry>
<term><filename>240-secureboot-policy.pcrlock</filename></term>
<listitem><para>The SecureBoot policy, as recorded to PCR 7. May be generated via
<command>systemd-pcrlock lock-secureboot-policy</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>250-firmware-code-early.pcrlock</filename></term>
<listitem><para>Firmware code measurements, as recorded to PCR 0 and 2, up to the separator
measurement (see <filename>400-secureboot-separator.pcrlock.</filename> below). May be generated via
<command>systemd-pcrlock lock-firmware-code</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>250-firmware-config-early.pcrlock</filename></term>
<listitem><para>Firmware configuration measurements, as recorded to PCR 1 and 3, up to the separator
measurement (see <filename>400-secureboot-separator.pcrlock.</filename> below). May be generated via
<command>systemd-pcrlock lock-firmware-config</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>350-action-efi-application.pcrlock</filename></term>
<listitem><para>The EFI "Application" measurement done once by the firmware. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>400-secureboot-separator.pcrlock</filename></term>
<listitem><para>The EFI "separator" measurement on PCR 7 done once by the firmware to indicate where
firmware control transitions into boot loader/OS control. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>500-separator.pcrlock</filename></term>
<listitem><para>The EFI "separator" measurements on PCRs 0-6 done once by the firmware to indicate
where firmware control transitions into boot loader/OS control. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>550-firmware-code-late.pcrlock</filename></term>
<listitem><para>Firmware code measurements, as recorded to PCR 0 and 2, after the separator
measurement (see <filename>400-secureboot-separator.pcrlock.</filename> above). May be generated via
<command>systemd-pcrlock lock-firmware-code</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>550-firmware-config-late.pcrlock</filename></term>
<listitem><para>Firmware configuration measurements, as recorded to PCR 1 and 3, after the separator
measurement (see <filename>400-secureboot-separator.pcrlock.</filename> above). May be generated via
<command>systemd-pcrlock lock-firmware-config</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>600-gpt.pcrlock</filename></term>
<listitem><para>The GPT partition table of the booted medium, as recorded to PCR 5 by the
firmware. May be generated via <command>systemd-pcrlock lock-gpt</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>620-secureboot-authority.pcrlock</filename></term>
<listitem><para>The SecureBoot authority, as recorded to PCR 7. May be generated via
<command>systemd-pcrlock lock-secureboot-authority</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>700-action-efi-exit-boot-services.pcrlock</filename></term>
<listitem><para>The EFI action generated when <function>ExitBootServices()</function> is generated,
i.e. the UEFI environment is left and the OS takes over. Covers the PCR 5 measurement. Statically
defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>710-kernel-cmdline.pcrlock</filename></term>
<listitem><para>The kernel command line, as measured by the Linux kernel to PCR 9. May be generated
via <command>systemd-pcrlock lock-kernel-cmdline</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>720-kernel-initrd.pcrlock</filename></term>
<listitem><para>The kernel initrd, as measured by the Linux kernel to PCR 9. May be generated
via <command>systemd-pcrlock lock-kernel-initrd</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>750-enter-initrd.pcrlock</filename></term>
<listitem><para>The measurement to PCR 11
<citerefentry><refentrytitle>systemd-pcrphase-initrd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
makes when the initrd initializes. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>800-leave-initrd.pcrlock</filename></term>
<listitem><para>The measurement to PCR 11
<citerefentry><refentrytitle>systemd-pcrphase-initrd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
makes when the initrd finishes. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>820-machine-id.pcrlock</filename></term>
<listitem><para>The measurement to PCR 15
<citerefentry><refentrytitle>systemd-pcrmachine.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
makes at boot, covering <filename>/etc/machine-id</filename> contents. May be generated via
<command>systemd-pcrlock lock-machine-id</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>830-root-file-system.pcrlock</filename></term>
<listitem><para>The measurement to PCR 15
<citerefentry><refentrytitle>systemd-pcrfs-root.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
makes at boot, covering the root file system identity. May be generated
via <command>systemd-pcrlock lock-file-system</command>.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>850-sysinit.pcrlock</filename></term>
<listitem><para>The measurement to PCR 11
<citerefentry><refentrytitle>systemd-pcrphase-sysinit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
makes when the main userspace did basic initialization and will now proceed to start regular system
services. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>900-ready.pcrlock</filename></term>
<listitem><para>The measurement to PCR 11
<citerefentry><refentrytitle>systemd-pcrphase.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
makes when the system fully booted up. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>950-shutdown.pcrlock</filename></term>
<listitem><para>The measurement to PCR 11
<citerefentry><refentrytitle>systemd-pcrphase.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
makes when the system begins shutdown. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
<varlistentry>
<term><filename>990-final.pcrlock</filename></term>
<listitem><para>The measurement to PCR 11
<citerefentry><refentrytitle>systemd-pcrphase-sysinit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
makes when the system is close to finishing shutdown. Statically defined.</para>
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-pcrlock</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@@ -174,6 +174,7 @@ profiledir = libexecdir / 'portable' / 'profile'
repartdefinitionsdir = libexecdir / 'repart/definitions'
ntpservicelistdir = prefixdir / 'lib/systemd/ntp-units.d'
credstoredir = prefixdir / 'lib/credstore'
pcrlockdir = prefixdir / 'lib/pcrlock.d'
configfiledir = get_option('configfiledir')
if configfiledir == ''
@@ -2176,6 +2177,7 @@ subdir('src/oom')
subdir('src/partition')
subdir('src/path')
subdir('src/pcrextend')
subdir('src/pcrlock')
subdir('src/portable')
subdir('src/pstore')
subdir('src/quotacheck')

View File

@@ -13,12 +13,14 @@
#include "efivars-fundamental.h"
#include "time-util.h"
#define EFI_VENDOR_LOADER SD_ID128_MAKE(4a,67,b0,82,0a,4c,41,cf,b6,c7,44,0b,29,bb,8c,4f)
#define EFI_VENDOR_LOADER_STR SD_ID128_MAKE_UUID_STR(4a,67,b0,82,0a,4c,41,cf,b6,c7,44,0b,29,bb,8c,4f)
#define EFI_VENDOR_GLOBAL SD_ID128_MAKE(8b,e4,df,61,93,ca,11,d2,aa,0d,00,e0,98,03,2b,8c)
#define EFI_VENDOR_GLOBAL_STR SD_ID128_MAKE_UUID_STR(8b,e4,df,61,93,ca,11,d2,aa,0d,00,e0,98,03,2b,8c)
#define EFI_VENDOR_SYSTEMD SD_ID128_MAKE(8c,f2,64,4b,4b,0b,42,8f,93,87,6d,87,60,50,dc,67)
#define EFI_VENDOR_SYSTEMD_STR SD_ID128_MAKE_UUID_STR(8c,f2,64,4b,4b,0b,42,8f,93,87,6d,87,60,50,dc,67)
#define EFI_VENDOR_LOADER SD_ID128_MAKE(4a,67,b0,82,0a,4c,41,cf,b6,c7,44,0b,29,bb,8c,4f)
#define EFI_VENDOR_LOADER_STR SD_ID128_MAKE_UUID_STR(4a,67,b0,82,0a,4c,41,cf,b6,c7,44,0b,29,bb,8c,4f)
#define EFI_VENDOR_GLOBAL SD_ID128_MAKE(8b,e4,df,61,93,ca,11,d2,aa,0d,00,e0,98,03,2b,8c)
#define EFI_VENDOR_GLOBAL_STR SD_ID128_MAKE_UUID_STR(8b,e4,df,61,93,ca,11,d2,aa,0d,00,e0,98,03,2b,8c)
#define EFI_VENDOR_DATABASE SD_ID128_MAKE(d7,19,b2,cb,3d,3a,45,96,a3,bc,da,d0,0e,67,65,6f)
#define EFI_VENDOR_DATABASE_STR SD_ID128_MAKE_UUID_STR(d7,19,b2,cb,3d,3a,45,96,a3,bc,da,d0,0e,67,65,6f)
#define EFI_VENDOR_SYSTEMD SD_ID128_MAKE(8c,f2,64,4b,4b,0b,42,8f,93,87,6d,87,60,50,dc,67)
#define EFI_VENDOR_SYSTEMD_STR SD_ID128_MAKE_UUID_STR(8c,f2,64,4b,4b,0b,42,8f,93,87,6d,87,60,50,dc,67)
#define EFI_VARIABLE_NON_VOLATILE UINT32_C(0x00000001)
#define EFI_VARIABLE_BOOTSERVICE_ACCESS UINT32_C(0x00000002)

View File

@@ -139,7 +139,8 @@ int enroll_tpm2(struct crypt_device *cd,
const char *pubkey_path,
uint32_t pubkey_pcr_mask,
const char *signature_path,
bool use_pin) {
bool use_pin,
const char *pcrlock_path) {
_cleanup_(erase_and_freep) void *secret = NULL;
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *signature_json = NULL;
@@ -207,6 +208,15 @@ int enroll_tpm2(struct crypt_device *cd,
return log_debug_errno(r, "Failed to read TPM PCR signature: %m");
}
_cleanup_(tpm2_pcrlock_policy_done) Tpm2PCRLockPolicy pcrlock_policy = {};
if (pcrlock_path) {
r = tpm2_pcrlock_policy_load(pcrlock_path, &pcrlock_policy);
if (r < 0)
return r;
flags |= TPM2_FLAGS_USE_PCRLOCK;
}
_cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
r = tpm2_context_new(device, &tpm2_context);
if (r < 0)
@@ -248,6 +258,7 @@ int enroll_tpm2(struct crypt_device *cd,
n_hash_pcr_values,
pubkey ? &public : NULL,
use_pin,
pcrlock_path ? &pcrlock_policy : NULL,
&policy);
if (r < 0)
return r;
@@ -288,6 +299,7 @@ int enroll_tpm2(struct crypt_device *cd,
pubkey_pcr_mask,
signature_json,
pin_str,
pcrlock_path ? &pcrlock_policy : NULL,
/* primary_alg= */ 0,
blob, blob_size,
policy.buffer, policy.size,

View File

@@ -8,9 +8,9 @@
#include "tpm2-util.h"
#if HAVE_TPM2
int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t seal_key_handle, Tpm2PCRValue *hash_pcrs, size_t n_hash_pcrs, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin);
int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t seal_key_handle, Tpm2PCRValue *hash_pcrs, size_t n_hash_pcrs, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin, const char *pcrlock_path);
#else
static inline int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t seal_key_handle, Tpm2PCRValue *hash_pcrs, size_t n_hash_pcrs, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin) {
static inline int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t seal_key_handle, Tpm2PCRValue *hash_pcrs, size_t n_hash_pcrs, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin, const char *pcrlock_path) {
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"TPM2 key enrollment not supported.");
}

View File

@@ -43,6 +43,7 @@ static bool arg_tpm2_pin = false;
static char *arg_tpm2_public_key = NULL;
static uint32_t arg_tpm2_public_key_pcr_mask = 0;
static char *arg_tpm2_signature = NULL;
static char *arg_tpm2_pcrlock = NULL;
static char *arg_node = NULL;
static int *arg_wipe_slots = NULL;
static size_t arg_n_wipe_slots = 0;
@@ -65,6 +66,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_hash_pcr_values, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_public_key, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_signature, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_pcrlock, freep);
STATIC_DESTRUCTOR_REGISTER(arg_node, freep);
STATIC_DESTRUCTOR_REGISTER(arg_wipe_slots, freep);
@@ -144,6 +146,8 @@ static int help(void) {
" --tpm2-signature=PATH\n"
" Validate public key enrollment works with JSON signature\n"
" file\n"
" --tpm2-pcrlock=PATH\n"
" Specify pcrlock policy to lock against\n"
" --tpm2-with-pin=BOOL\n"
" Whether to require entering a PIN to unlock the volume\n"
"\nSee the %2$s for details.\n",
@@ -173,6 +177,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_TPM2_PUBLIC_KEY_PCRS,
ARG_TPM2_SIGNATURE,
ARG_TPM2_PIN,
ARG_TPM2_PCRLOCK,
ARG_WIPE_SLOT,
ARG_FIDO2_WITH_PIN,
ARG_FIDO2_WITH_UP,
@@ -200,11 +205,12 @@ static int parse_argv(int argc, char *argv[]) {
{ "tpm2-public-key-pcrs", required_argument, NULL, ARG_TPM2_PUBLIC_KEY_PCRS },
{ "tpm2-signature", required_argument, NULL, ARG_TPM2_SIGNATURE },
{ "tpm2-with-pin", required_argument, NULL, ARG_TPM2_PIN },
{ "tpm2-pcrlock", required_argument, NULL, ARG_TPM2_PCRLOCK },
{ "wipe-slot", required_argument, NULL, ARG_WIPE_SLOT },
{}
};
bool auto_hash_pcr_values = true, auto_public_key_pcr_mask = true;
bool auto_hash_pcr_values = true, auto_public_key_pcr_mask = true, auto_pcrlock = true;
int c, r;
assert(argc >= 0);
@@ -412,6 +418,14 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_TPM2_PCRLOCK:
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_tpm2_pcrlock);
if (r < 0)
return r;
auto_pcrlock = false;
break;
case ARG_WIPE_SLOT: {
const char *p = optarg;
@@ -500,12 +514,23 @@ static int parse_argv(int argc, char *argv[]) {
}
}
if (auto_pcrlock) {
assert(!arg_tpm2_pcrlock);
r = tpm2_pcrlock_search_file(NULL, NULL, &arg_tpm2_pcrlock);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Search for pcrlock.json failed, assuming it does not exist: %m");
} else
log_info("Automatically using pcrlock policy '%s'.", arg_tpm2_pcrlock);
}
if (auto_public_key_pcr_mask) {
assert(arg_tpm2_public_key_pcr_mask == 0);
arg_tpm2_public_key_pcr_mask = INDEX_TO_MASK(uint32_t, TPM2_PCR_KERNEL_BOOT);
}
if (auto_hash_pcr_values) {
if (auto_hash_pcr_values && !arg_tpm2_pcrlock) { /* Only lock to PCR 7 by default if no pcrlock policy is around (which is a better replacement) */
assert(arg_tpm2_n_hash_pcr_values == 0);
if (!GREEDY_REALLOC_APPEND(
@@ -690,7 +715,7 @@ static int run(int argc, char *argv[]) {
break;
case ENROLL_TPM2:
slot = enroll_tpm2(cd, vk, vks, arg_tpm2_device, arg_tpm2_seal_key_handle, arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values, arg_tpm2_public_key, arg_tpm2_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin);
slot = enroll_tpm2(cd, vk, vks, arg_tpm2_device, arg_tpm2_seal_key_handle, arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values, arg_tpm2_public_key, arg_tpm2_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin, arg_tpm2_pcrlock);
break;
case _ENROLL_TYPE_INVALID:

View File

@@ -109,6 +109,7 @@ _public_ int cryptsetup_token_open_pin(
pubkey_pcr_mask,
params.signature_path,
pin_string,
params.pcrlock_path,
primary_alg,
blob,
blob_size,
@@ -239,6 +240,7 @@ _public_ void cryptsetup_token_dump(
crypt_log(cd, "\ttpm2-blob: %s\n", blob_str);
crypt_log(cd, "\ttpm2-policy-hash:" CRYPT_DUMP_LINE_SEP "%s\n", policy_hash_str);
crypt_log(cd, "\ttpm2-pin: %s\n", true_false(flags & TPM2_FLAGS_USE_PIN));
crypt_log(cd, "\ttpm2-pcrlock: %s\n", true_false(flags & TPM2_FLAGS_USE_PCRLOCK));
crypt_log(cd, "\ttpm2-salt: %s\n", true_false(salt));
crypt_log(cd, "\ttpm2-srk: %s\n", true_false(srk_buf));
}

View File

@@ -22,6 +22,7 @@ int acquire_luks2_key(
uint32_t pubkey_pcr_mask,
const char *signature_path,
const char *pin,
const char *pcrlock_path,
uint16_t primary_alg,
const void *key_data,
size_t key_data_size,
@@ -76,6 +77,13 @@ int acquire_luks2_key(
return log_error_errno(r, "Failed to load PCR signature: %m");
}
_cleanup_(tpm2_pcrlock_policy_done) Tpm2PCRLockPolicy pcrlock_policy = {};
if (FLAGS_SET(flags, TPM2_FLAGS_USE_PCRLOCK)) {
r = tpm2_pcrlock_policy_load(pcrlock_path, &pcrlock_policy);
if (r < 0)
return r;
}
_cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
r = tpm2_context_new(device, &tpm2_context);
if (r < 0)
@@ -88,6 +96,7 @@ int acquire_luks2_key(
pubkey_pcr_mask,
signature_json,
pin,
FLAGS_SET(flags, TPM2_FLAGS_USE_PCRLOCK) ? &pcrlock_policy : NULL,
primary_alg,
key_data, key_data_size,
policy_hash, policy_hash_size,

View File

@@ -14,6 +14,7 @@ int acquire_luks2_key(
size_t pubkey_size,
uint32_t pubkey_pcr_mask,
const char *signature_path,
const char *pcrlock_path,
const char *pin,
uint16_t primary_alg,
const void *key_data,

View File

@@ -62,6 +62,7 @@ int acquire_tpm2_key(
size_t pubkey_size,
uint32_t pubkey_pcr_mask,
const char *signature_path,
const char *pcrlock_path,
uint16_t primary_alg,
const char *key_file,
size_t key_file_size,
@@ -129,6 +130,14 @@ int acquire_tpm2_key(
return log_error_errno(r, "Failed to load pcr signature: %m");
}
_cleanup_(tpm2_pcrlock_policy_done) Tpm2PCRLockPolicy pcrlock_policy = {};
if (FLAGS_SET(flags, TPM2_FLAGS_USE_PCRLOCK)) {
r = tpm2_pcrlock_policy_load(pcrlock_path, &pcrlock_policy);
if (r < 0)
return r;
}
_cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
r = tpm2_context_new(device, &tpm2_context);
if (r < 0)
@@ -142,6 +151,7 @@ int acquire_tpm2_key(
pubkey_pcr_mask,
signature_json,
/* pin= */ NULL,
FLAGS_SET(flags, TPM2_FLAGS_USE_PCRLOCK) ? &pcrlock_policy : NULL,
primary_alg,
blob,
blob_size,
@@ -189,6 +199,7 @@ int acquire_tpm2_key(
pubkey_pcr_mask,
signature_json,
b64_salted_pin,
pcrlock_path ? &pcrlock_policy : NULL,
primary_alg,
blob,
blob_size,

View File

@@ -20,6 +20,7 @@ int acquire_tpm2_key(
size_t pubkey_size,
uint32_t pubkey_pcr_mask,
const char *signature_path,
const char *pcrlock_path,
uint16_t primary_alg,
const char *key_file,
size_t key_file_size,
@@ -72,6 +73,7 @@ static inline int acquire_tpm2_key(
size_t pubkey_size,
uint32_t pubkey_pcr_mask,
const char *signature_path,
const char *pcrlock_path,
uint16_t primary_alg,
const char *key_file,
size_t key_file_size,

View File

@@ -100,6 +100,7 @@ static bool arg_tpm2_device_auto = false;
static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
static char *arg_tpm2_signature = NULL;
static bool arg_tpm2_pin = false;
static char *arg_tpm2_pcrlock = NULL;
static bool arg_headless = false;
static usec_t arg_token_timeout_usec = 30*USEC_PER_SEC;
static unsigned arg_tpm2_measure_pcr = UINT_MAX; /* This and the following field is about measuring the unlocked volume key to the local TPM */
@@ -116,6 +117,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_fido2_rp_id, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_signature, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_measure_banks, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_pcrlock, freep);
static const char* const passphrase_type_table[_PASSPHRASE_TYPE_MAX] = {
[PASSPHRASE_REGULAR] = "passphrase",
@@ -424,6 +426,16 @@ static int parse_one_option(const char *option) {
arg_tpm2_pin = r;
} else if ((val = startswith(option, "tpm2-pcrlock="))) {
if (!path_is_absolute(val))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"TPM2 pcrlock policy path \"%s\" is not absolute, refusing.", val);
r = free_and_strdup(&arg_tpm2_pcrlock, val);
if (r < 0)
return log_oom();
} else if ((val = startswith(option, "tpm2-measure-pcr="))) {
unsigned pcr;
@@ -1605,6 +1617,7 @@ static int attach_luks2_by_tpm2_via_plugin(
.search_pcr_mask = arg_tpm2_pcr_mask,
.device = arg_tpm2_device,
.signature_path = arg_tpm2_signature,
.pcrlock_path = arg_tpm2_pcrlock,
};
if (!libcryptsetup_plugins_support())
@@ -1664,6 +1677,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
/* pubkey= */ NULL, /* pubkey_size= */ 0,
/* pubkey_pcr_mask= */ 0,
/* signature_path= */ NULL,
/* pcrlock_path= */ NULL,
/* primary_alg= */ 0,
key_file, arg_keyfile_size, arg_keyfile_offset,
key_data, key_data_size,
@@ -1761,6 +1775,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
pubkey, pubkey_size,
pubkey_pcr_mask,
arg_tpm2_signature,
arg_tpm2_pcrlock,
primary_alg,
/* key_file= */ NULL, /* key_file_size= */ 0, /* key_file_offset= */ 0, /* no key file */
blob, blob_size,

View File

@@ -152,6 +152,7 @@ static Tpm2PCRValue *arg_tpm2_hash_pcr_values = NULL;
static size_t arg_tpm2_n_hash_pcr_values = 0;
static char *arg_tpm2_public_key = NULL;
static uint32_t arg_tpm2_public_key_pcr_mask = 0;
static char *arg_tpm2_pcrlock = NULL;
static bool arg_split = false;
static GptPartitionType *arg_filter_partitions = NULL;
static size_t arg_n_filter_partitions = 0;
@@ -175,6 +176,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_certificate, X509_freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_hash_pcr_values, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_public_key, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_pcrlock, freep);
STATIC_DESTRUCTOR_REGISTER(arg_filter_partitions, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
STATIC_DESTRUCTOR_REGISTER(arg_copy_from, strv_freep);
@@ -3821,8 +3823,21 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta
return log_error_errno(r, "Could not get hash mask: %m");
}
_cleanup_(tpm2_pcrlock_policy_done) Tpm2PCRLockPolicy pcrlock_policy = {};
if (arg_tpm2_pcrlock) {
r = tpm2_pcrlock_policy_load(arg_tpm2_pcrlock, &pcrlock_policy);
if (r < 0)
return r;
}
TPM2B_DIGEST policy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE);
r = tpm2_calculate_sealing_policy(arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values, pubkey ? &public : NULL, /* use_pin= */ false, &policy);
r = tpm2_calculate_sealing_policy(
arg_tpm2_hash_pcr_values,
arg_tpm2_n_hash_pcr_values,
pubkey ? &public : NULL,
/* use_pin= */ false,
arg_tpm2_pcrlock ? &pcrlock_policy : NULL,
&policy);
if (r < 0)
return log_error_errno(r, "Could not calculate sealing policy digest: %m");
@@ -6435,6 +6450,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_TPM2_PCRS,
ARG_TPM2_PUBLIC_KEY,
ARG_TPM2_PUBLIC_KEY_PCRS,
ARG_TPM2_PCRLOCK,
ARG_SPLIT,
ARG_INCLUDE_PARTITIONS,
ARG_EXCLUDE_PARTITIONS,
@@ -6472,6 +6488,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "tpm2-pcrs", required_argument, NULL, ARG_TPM2_PCRS },
{ "tpm2-public-key", required_argument, NULL, ARG_TPM2_PUBLIC_KEY },
{ "tpm2-public-key-pcrs", required_argument, NULL, ARG_TPM2_PUBLIC_KEY_PCRS },
{ "tpm2-pcrlock", required_argument, NULL, ARG_TPM2_PCRLOCK },
{ "split", required_argument, NULL, ARG_SPLIT },
{ "include-partitions", required_argument, NULL, ARG_INCLUDE_PARTITIONS },
{ "exclude-partitions", required_argument, NULL, ARG_EXCLUDE_PARTITIONS },
@@ -6485,7 +6502,7 @@ static int parse_argv(int argc, char *argv[]) {
{}
};
bool auto_hash_pcr_values = true, auto_public_key_pcr_mask = true;
bool auto_hash_pcr_values = true, auto_public_key_pcr_mask = true, auto_pcrlock = true;
int c, r;
assert(argc >= 0);
@@ -6728,6 +6745,14 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_TPM2_PCRLOCK:
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_tpm2_pcrlock);
if (r < 0)
return r;
auto_pcrlock = false;
break;
case ARG_SPLIT:
r = parse_boolean_argument("--split=", optarg, NULL);
if (r < 0)
@@ -6935,12 +6960,23 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"A path to an image file must be specified when --split is used.");
if (auto_pcrlock) {
assert(!arg_tpm2_pcrlock);
r = tpm2_pcrlock_search_file(NULL, NULL, &arg_tpm2_pcrlock);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Search for pcrlock.json failed, assuming it does not exist: %m");
} else
log_info("Automatically using pcrlock policy '%s'.", arg_tpm2_pcrlock);
}
if (auto_public_key_pcr_mask) {
assert(arg_tpm2_public_key_pcr_mask == 0);
arg_tpm2_public_key_pcr_mask = INDEX_TO_MASK(uint32_t, TPM2_PCR_KERNEL_BOOT);
}
if (auto_hash_pcr_values) {
if (auto_hash_pcr_values && !arg_tpm2_pcrlock) { /* Only lock to PCR 7 if no pcr policy is specified. */
assert(arg_tpm2_n_hash_pcr_values == 0);
if (!GREEDY_REALLOC_APPEND(

37
src/pcrlock/meson.build Normal file
View File

@@ -0,0 +1,37 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
executables += [
libexec_template + {
'name' : 'systemd-pcrlock',
'conditions' : [
'HAVE_OPENSSL',
'HAVE_TPM2'
],
'sources' : files(
'pcrlock.c',
'pcrlock-firmware.c',
'pehash.c',
),
'dependencies' : [
libm,
libopenssl,
tpm2,
],
},
]
if conf.get('HAVE_OPENSSL') == 1 and conf.get('HAVE_TPM2') == 1
install_data('pcrlock.d/350-action-efi-application.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/400-secureboot-separator.pcrlock.d/300-0x00000000.pcrlock', install_dir : pcrlockdir / '400-secureboot-separator.pcrlock.d')
install_data('pcrlock.d/400-secureboot-separator.pcrlock.d/600-0xffffffff.pcrlock', install_dir : pcrlockdir / '400-secureboot-separator.pcrlock.d')
install_data('pcrlock.d/500-separator.pcrlock.d/300-0x00000000.pcrlock', install_dir : pcrlockdir / '500-separator.pcrlock.d')
install_data('pcrlock.d/500-separator.pcrlock.d/600-0xffffffff.pcrlock', install_dir : pcrlockdir / '500-separator.pcrlock.d')
install_data('pcrlock.d/700-action-efi-exit-boot-services.pcrlock.d/300-present.pcrlock', install_dir : pcrlockdir / '700-action-efi-exit-boot-services.pcrlock.d')
install_data('pcrlock.d/700-action-efi-exit-boot-services.pcrlock.d/600-absent.pcrlock', install_dir : pcrlockdir / '700-action-efi-exit-boot-services.pcrlock.d')
install_data('pcrlock.d/750-enter-initrd.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/800-leave-initrd.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/850-sysinit.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/900-ready.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/950-shutdown.pcrlock', install_dir : pcrlockdir)
install_data('pcrlock.d/990-final.pcrlock', install_dir : pcrlockdir)
endif

Some files were not shown because too many files have changed in this diff Show More