Merge pull request #29301 from poettering/pcr-extend-rename

rename pcrphase binary to pcrextend
This commit is contained in:
Lennart Poettering
2023-09-25 18:28:03 +02:00
committed by GitHub
16 changed files with 102 additions and 49 deletions
+1 -1
View File
@@ -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
View File
@@ -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
+2 -2
View File
@@ -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'],
+2 -1
View File
@@ -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
+36 -3
View File
@@ -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>
+1
View File
@@ -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')
-15
View File
@@ -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'),
+19
View File
@@ -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 -5
View File
@@ -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
+1 -1
View File
@@ -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=/
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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