Merge pull request #29301 from poettering/pcr-extend-rename
rename pcrphase binary to pcrextend
This commit is contained in:
@@ -144,7 +144,7 @@ Features:
|
||||
* automatically mount one virtiofs during early boot phase to /run/host/,
|
||||
similar to how we do that for nspawn, based on some clear tag.
|
||||
|
||||
* make systemd-pcrphase accessible via varlink so that clients can measure
|
||||
* make systemd-pcrextend accessible via varlink so that clients can measure
|
||||
things reasonably freely, and get a proper entry in the TPM event log we
|
||||
maintain, correctly synchronized
|
||||
|
||||
|
||||
+1
-1
@@ -536,7 +536,7 @@ SYSTEMD_HOME_DEBUG_SUFFIX=foo \
|
||||
* `$SYSTEMD_CATALOG_SOURCES` – path to the catalog database input source
|
||||
directory to use for `journalctl --update-catalog`.
|
||||
|
||||
`systemd-pcrphase`, `systemd-cryptsetup`:
|
||||
`systemd-pcrextend`, `systemd-cryptsetup`:
|
||||
|
||||
* `$SYSTEMD_FORCE_MEASURE=1` — If set, force measuring of resources (which are
|
||||
marked for measurement) even if not booted on a kernel equipped with
|
||||
|
||||
@@ -1005,10 +1005,10 @@ manpages = [
|
||||
['systemd-path', '1', [], ''],
|
||||
['systemd-pcrphase.service',
|
||||
'8',
|
||||
['systemd-pcrfs-root.service',
|
||||
['systemd-pcrextend',
|
||||
'systemd-pcrfs-root.service',
|
||||
'systemd-pcrfs@.service',
|
||||
'systemd-pcrmachine.service',
|
||||
'systemd-pcrphase',
|
||||
'systemd-pcrphase-initrd.service',
|
||||
'systemd-pcrphase-sysinit.service'],
|
||||
'ENABLE_BOOTLOADER'],
|
||||
|
||||
@@ -191,7 +191,8 @@
|
||||
<listitem><para>Controls which boot phases to calculate expected PCR 11 values for. This takes a
|
||||
series of colon-separated strings that encode boot "paths" for entering a specific phase of the boot
|
||||
process. Each of the specified strings is measured by the
|
||||
<filename>systemd-pcrphase-initrd.service</filename> and
|
||||
<filename>systemd-pcrphase-initrd.service</filename>,
|
||||
<filename>systemd-pcrphase-sysinit.service</filename>, and
|
||||
<citerefentry><refentrytitle>systemd-pcrphase.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
into PCR 11 during different milestones of the boot process. This switch may be specified multiple
|
||||
times to calculate PCR values for multiple boot phases at once. If not used defaults to
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<refname>systemd-pcrmachine.service</refname>
|
||||
<refname>systemd-pcrfs-root.service</refname>
|
||||
<refname>systemd-pcrfs@.service</refname>
|
||||
<refname>systemd-pcrphase</refname>
|
||||
<refname>systemd-pcrextend</refname>
|
||||
<refpurpose>Measure boot phase into TPM2 PCR 11, machine ID and file system identity into PCR 15</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<para><filename>systemd-pcrmachine.service</filename></para>
|
||||
<para><filename>systemd-pcrfs-root.service</filename></para>
|
||||
<para><filename>systemd-pcrfs@.service</filename></para>
|
||||
<para><filename>/usr/lib/systemd/systemd-pcrphase</filename> <optional><replaceable>STRING</replaceable></optional></para>
|
||||
<para><filename>/usr/lib/systemd/systemd-pcrextend</filename> <optional><replaceable>STRING</replaceable></optional></para>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
@@ -134,7 +134,7 @@
|
||||
<refsect1>
|
||||
<title>Options</title>
|
||||
|
||||
<para>The <filename>/usr/lib/systemd/system-pcrphase</filename> executable may also be invoked from the
|
||||
<para>The <filename>/usr/lib/systemd/system-pcrextend</filename> executable may also be invoked from the
|
||||
command line, where it expects the word to extend into PCR 11, as well as the following switches:</para>
|
||||
|
||||
<variablelist>
|
||||
@@ -148,6 +148,15 @@
|
||||
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--pcr=</option></term>
|
||||
|
||||
<listitem><para>Takes the index of the PCR to extend. If <option>--machine-id</option> or
|
||||
<option>--file-system=</option> are specified defaults to 15, otherwise defaults to 11.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--tpm2-device=</option><replaceable>PATH</replaceable></term>
|
||||
|
||||
@@ -195,6 +204,30 @@
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Files</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>/var/log/systemd/tpm2-measure.log</filename></term>
|
||||
|
||||
<listitem><para>Measurements are logged into an event log file maintained in
|
||||
<filename>/var/log/systemd/tpm2-measure.log</filename>, which contains a <ulink
|
||||
url="https://www.rfc-editor.org/rfc/rfc7464.html">JSON-SEQ</ulink> series of objects that follow the
|
||||
general structure of the <ulink
|
||||
url="https://trustedcomputinggroup.org/resource/canonical-event-log-format/">TCG Common Event Log
|
||||
Format (CEL-JSON)</ulink> event objects (but lack the <literal>recnum</literal>
|
||||
field).</para>
|
||||
|
||||
<para>A <constant>LOCK_EX</constant> BSD file lock (<citerefentry
|
||||
project='man-pages'><refentrytitle>flock</refentrytitle><manvolnum>2</manvolnum></citerefentry>) on
|
||||
the log file is acquired while the measurement is made and the file is updated. Thus, applications
|
||||
that intend to acquire a consistent quote from the TPM with the associated snapshot of the event log
|
||||
should acquire a <constant>LOCK_SH</constant> lock while doing so.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
<para>
|
||||
|
||||
@@ -2158,6 +2158,7 @@ subdir('src/nss-systemd')
|
||||
subdir('src/oom')
|
||||
subdir('src/partition')
|
||||
subdir('src/path')
|
||||
subdir('src/pcrextend')
|
||||
subdir('src/portable')
|
||||
subdir('src/pstore')
|
||||
subdir('src/quotacheck')
|
||||
|
||||
@@ -64,21 +64,6 @@ executables += [
|
||||
'sources' : files('measure.c'),
|
||||
'dependencies' : libopenssl,
|
||||
},
|
||||
libexec_template + {
|
||||
'name' : 'systemd-pcrphase',
|
||||
'conditions' : [
|
||||
'HAVE_BLKID',
|
||||
'ENABLE_BOOTLOADER',
|
||||
'HAVE_OPENSSL',
|
||||
'HAVE_TPM2',
|
||||
],
|
||||
'sources' : files('pcrphase.c'),
|
||||
'dependencies' : [
|
||||
libblkid,
|
||||
libopenssl,
|
||||
tpm2,
|
||||
],
|
||||
},
|
||||
libexec_template + {
|
||||
'name' : 'systemd-boot-check-no-failures',
|
||||
'sources' : files('boot-check-no-failures.c'),
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
executables += [
|
||||
libexec_template + {
|
||||
'name' : 'systemd-pcrextend',
|
||||
'conditions' : [
|
||||
'HAVE_BLKID',
|
||||
'ENABLE_BOOTLOADER',
|
||||
'HAVE_OPENSSL',
|
||||
'HAVE_TPM2',
|
||||
],
|
||||
'sources' : files('pcrextend.c'),
|
||||
'dependencies' : [
|
||||
libblkid,
|
||||
libopenssl,
|
||||
tpm2,
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "mountpoint-util.h"
|
||||
#include "openssl-util.h"
|
||||
#include "parse-argument.h"
|
||||
#include "parse-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "tpm2-pcr.h"
|
||||
#include "tpm2-util.h"
|
||||
@@ -26,6 +27,7 @@ static char *arg_tpm2_device = NULL;
|
||||
static char **arg_banks = NULL;
|
||||
static char *arg_file_system = NULL;
|
||||
static bool arg_machine_id = false;
|
||||
static unsigned arg_pcr_index = UINT_MAX;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_banks, strv_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
|
||||
@@ -35,18 +37,19 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("systemd-pcrphase", "8", &link);
|
||||
r = terminal_urlify_man("systemd-pcrextend", "8", &link);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
printf("%1$s [OPTIONS...] WORD\n"
|
||||
"%1$s [OPTIONS...] --file-system=PATH\n"
|
||||
"%1$s [OPTIONS...] --machine-id\n"
|
||||
"\n%5$sMeasure boot phase into TPM2 PCR 11.%6$s\n"
|
||||
"\n%5$sExtend a TPM2 PCR with boot phase, machine ID, or file system ID.%6$s\n"
|
||||
"\n%3$sOptions:%4$s\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Print version\n"
|
||||
" --bank=DIGEST Select TPM bank (SHA1, SHA256)\n"
|
||||
" --bank=DIGEST Select TPM PCR bank (SHA1, SHA256)\n"
|
||||
" --pcr=INDEX Select TPM PCR index (0…23)\n"
|
||||
" --tpm2-device=PATH Use specified TPM2 device\n"
|
||||
" --graceful Exit gracefully if no TPM2 device is found\n"
|
||||
" --file-system=PATH Measure UUID/labels of file system into PCR 15\n"
|
||||
@@ -66,6 +69,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_BANK,
|
||||
ARG_PCR,
|
||||
ARG_TPM2_DEVICE,
|
||||
ARG_GRACEFUL,
|
||||
ARG_FILE_SYSTEM,
|
||||
@@ -76,6 +80,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "bank", required_argument, NULL, ARG_BANK },
|
||||
{ "pcr", required_argument, NULL, ARG_PCR },
|
||||
{ "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE },
|
||||
{ "graceful", no_argument, NULL, ARG_GRACEFUL },
|
||||
{ "file-system", required_argument, NULL, ARG_FILE_SYSTEM },
|
||||
@@ -111,6 +116,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ARG_PCR:
|
||||
r = tpm2_pcr_index_from_string(optarg);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse PCR index: %s", optarg);
|
||||
|
||||
arg_pcr_index = r;
|
||||
break;
|
||||
|
||||
case ARG_TPM2_DEVICE: {
|
||||
_cleanup_free_ char *device = NULL;
|
||||
|
||||
@@ -152,6 +165,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (arg_file_system && arg_machine_id)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--file-system= and --machine-id may not be combined.");
|
||||
|
||||
if (arg_pcr_index == UINT_MAX)
|
||||
arg_pcr_index = (arg_file_system || arg_machine_id) ?
|
||||
TPM2_PCR_SYSTEM_IDENTITY : /* → PCR 15 */
|
||||
TPM2_PCR_KERNEL_BOOT; /* → PCR 11 */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -242,7 +260,6 @@ static int get_file_system_word(
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_free_ char *joined = NULL, *word = NULL;
|
||||
Tpm2UserspaceEventType event;
|
||||
unsigned target_pcr_nr;
|
||||
size_t length;
|
||||
int r;
|
||||
|
||||
@@ -291,7 +308,6 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(r, "Failed to get file system identifier string for '%s': %m", arg_file_system);
|
||||
}
|
||||
|
||||
target_pcr_nr = TPM2_PCR_SYSTEM_IDENTITY; /* → PCR 15 */
|
||||
event = TPM2_EVENT_FILESYSTEM;
|
||||
|
||||
} else if (arg_machine_id) {
|
||||
@@ -308,7 +324,6 @@ static int run(int argc, char *argv[]) {
|
||||
if (!word)
|
||||
return log_oom();
|
||||
|
||||
target_pcr_nr = TPM2_PCR_SYSTEM_IDENTITY; /* → PCR 15 */
|
||||
event = TPM2_EVENT_MACHINE_ID;
|
||||
|
||||
} else {
|
||||
@@ -325,7 +340,6 @@ static int run(int argc, char *argv[]) {
|
||||
if (isempty(word))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "String to measure cannot be empty, refusing.");
|
||||
|
||||
target_pcr_nr = TPM2_PCR_KERNEL_BOOT; /* → PCR 11 */
|
||||
event = TPM2_EVENT_PHASE;
|
||||
}
|
||||
|
||||
@@ -350,7 +364,7 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = determine_banks(c, target_pcr_nr);
|
||||
r = determine_banks(c, arg_pcr_index);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (strv_isempty(arg_banks)) /* Still none? */
|
||||
@@ -360,17 +374,17 @@ static int run(int argc, char *argv[]) {
|
||||
if (!joined)
|
||||
return log_oom();
|
||||
|
||||
log_debug("Measuring '%s' into PCR index %u, banks %s.", word, target_pcr_nr, joined);
|
||||
log_debug("Measuring '%s' into PCR index %u, banks %s.", word, arg_pcr_index, joined);
|
||||
|
||||
r = tpm2_extend_bytes(c, arg_banks, target_pcr_nr, word, length, NULL, 0, event, word);
|
||||
r = tpm2_extend_bytes(c, arg_banks, arg_pcr_index, word, length, NULL, 0, event, word);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
log_struct(LOG_INFO,
|
||||
"MESSAGE_ID=" SD_MESSAGE_TPM_PCR_EXTEND_STR,
|
||||
LOG_MESSAGE("Extended PCR index %u with '%s' (banks %s).", target_pcr_nr, word, joined),
|
||||
LOG_MESSAGE("Extended PCR index %u with '%s' (banks %s).", arg_pcr_index, word, joined),
|
||||
"MEASURING=%s", word,
|
||||
"PCR=%u", target_pcr_nr,
|
||||
"PCR=%u", arg_pcr_index,
|
||||
"BANKS=%s", joined);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
@@ -5,7 +5,7 @@ set -o pipefail
|
||||
|
||||
SD_CRYPTSETUP="/usr/lib/systemd/systemd-cryptsetup"
|
||||
SD_MEASURE="/usr/lib/systemd/systemd-measure"
|
||||
SD_PCRPHASE="/usr/lib/systemd/systemd-pcrphase"
|
||||
SD_PCREXTEND="/usr/lib/systemd/systemd-pcrextend"
|
||||
export SYSTEMD_LOG_LEVEL=debug
|
||||
|
||||
cryptsetup_has_token_plugin_support() {
|
||||
@@ -249,12 +249,12 @@ else
|
||||
echo "$SD_MEASURE or PCR sysfs files not found, skipping signed PCR policy test case"
|
||||
fi
|
||||
|
||||
if [[ -x "$SD_PCRPHASE" ]] && tpm_has_pcr sha256 11 && tpm_has_pcr sha256 15; then
|
||||
if [[ -x "$SD_PCREXTEND" ]] && tpm_has_pcr sha256 11 && tpm_has_pcr sha256 15; then
|
||||
# Let's measure the machine ID
|
||||
tpm2_pcrread sha256:15 -Q -o /tmp/oldpcr15
|
||||
mv /etc/machine-id /etc/machine-id.save
|
||||
echo 994013bf23864ee7992eab39a96dd3bb >/etc/machine-id
|
||||
SYSTEMD_FORCE_MEASURE=1 "$SD_PCRPHASE" --machine-id
|
||||
SYSTEMD_FORCE_MEASURE=1 "$SD_PCREXTEND" --machine-id
|
||||
mv /etc/machine-id.save /etc/machine-id
|
||||
tpm2_pcrread sha256:15 -Q -o /tmp/newpcr15
|
||||
|
||||
@@ -270,7 +270,7 @@ if [[ -x "$SD_PCRPHASE" ]] && tpm_has_pcr sha256 11 && tpm_has_pcr sha256 15; th
|
||||
|
||||
# And similar for the boot phase measurement into PCR 11
|
||||
tpm2_pcrread sha256:11 -Q -o /tmp/oldpcr11
|
||||
SYSTEMD_FORCE_MEASURE=1 "$SD_PCRPHASE" foobar
|
||||
SYSTEMD_FORCE_MEASURE=1 "$SD_PCREXTEND" foobar
|
||||
tpm2_pcrread sha256:11 -Q -o /tmp/newpcr11
|
||||
|
||||
diff /tmp/newpcr11 \
|
||||
@@ -284,7 +284,7 @@ if [[ -x "$SD_PCRPHASE" ]] && tpm_has_pcr sha256 11 && tpm_has_pcr sha256 15; th
|
||||
|
||||
rm -f /tmp/oldpcr11 /tmp/newpcr11
|
||||
else
|
||||
echo "$SD_PCRPHASE or PCR sysfs files not found, skipping PCR extension test case"
|
||||
echo "$SD_PCREXTEND or PCR sysfs files not found, skipping PCR extension test case"
|
||||
fi
|
||||
|
||||
# Ensure that sandboxing doesn't stop creds from being accessible
|
||||
|
||||
@@ -21,4 +21,4 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrphase --graceful --file-system=/
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrextend --graceful --file-system=/
|
||||
|
||||
@@ -22,4 +22,4 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrphase --graceful --file-system=%f
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrextend --graceful --file-system=%f
|
||||
|
||||
@@ -20,4 +20,4 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrphase --graceful --machine-id
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrextend --graceful --machine-id
|
||||
|
||||
@@ -20,5 +20,5 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrphase --graceful enter-initrd
|
||||
ExecStop={{LIBEXECDIR}}/systemd-pcrphase --graceful leave-initrd
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrextend --graceful enter-initrd
|
||||
ExecStop={{LIBEXECDIR}}/systemd-pcrextend --graceful leave-initrd
|
||||
|
||||
@@ -21,5 +21,5 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrphase --graceful sysinit
|
||||
ExecStop={{LIBEXECDIR}}/systemd-pcrphase --graceful final
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrextend --graceful sysinit
|
||||
ExecStop={{LIBEXECDIR}}/systemd-pcrextend --graceful final
|
||||
|
||||
@@ -19,5 +19,5 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrphase --graceful ready
|
||||
ExecStop={{LIBEXECDIR}}/systemd-pcrphase --graceful shutdown
|
||||
ExecStart={{LIBEXECDIR}}/systemd-pcrextend --graceful ready
|
||||
ExecStop={{LIBEXECDIR}}/systemd-pcrextend --graceful shutdown
|
||||
|
||||
Reference in New Issue
Block a user