mirror of
https://github.com/systemd/systemd
synced 2024-10-06 16:21:34 +00:00
boot: add new pcrphase tool to measure barrier strings into PCR 11
This commit is contained in:
parent
c5bf1f85cb
commit
708d752479
|
@ -527,3 +527,15 @@ Support: %SUPPORT_URL%
|
||||||
|
|
||||||
For the first time during the current boot an NTP synchronization has been
|
For the first time during the current boot an NTP synchronization has been
|
||||||
acquired and the local system clock adjustment has been initiated.
|
acquired and the local system clock adjustment has been initiated.
|
||||||
|
|
||||||
|
-- 3f7d5ef3e54f4302b4f0b143bb270cab
|
||||||
|
Subject: TPM PCR Extended
|
||||||
|
Defined-By: systemd
|
||||||
|
Support: %SUPPORT_URL%
|
||||||
|
|
||||||
|
The string '@MEASURING@' has been extended into Trusted Platform Module's (TPM)
|
||||||
|
Platform Configuration Register (PCR) @PCR@, on banks @BANKS@.
|
||||||
|
|
||||||
|
Whenever the system transitions to a new runtime phase, a different string is
|
||||||
|
extended into the specified PCR, to ensure that security policies for TPM-bound
|
||||||
|
secrets and other resources are limited to specific phases of the runtime.
|
||||||
|
|
|
@ -966,6 +966,10 @@ manpages = [
|
||||||
['systemd-nspawn', '1', [], ''],
|
['systemd-nspawn', '1', [], ''],
|
||||||
['systemd-oomd.service', '8', ['systemd-oomd'], 'ENABLE_OOMD'],
|
['systemd-oomd.service', '8', ['systemd-oomd'], 'ENABLE_OOMD'],
|
||||||
['systemd-path', '1', [], ''],
|
['systemd-path', '1', [], ''],
|
||||||
|
['systemd-pcrphase.service',
|
||||||
|
'8',
|
||||||
|
['systemd-pcrphase', 'systemd-pcrphase-initrd.service'],
|
||||||
|
'HAVE_GNU_EFI'],
|
||||||
['systemd-portabled.service', '8', ['systemd-portabled'], 'ENABLE_PORTABLED'],
|
['systemd-portabled.service', '8', ['systemd-portabled'], 'ENABLE_PORTABLED'],
|
||||||
['systemd-pstore.service', '8', ['systemd-pstore'], 'ENABLE_PSTORE'],
|
['systemd-pstore.service', '8', ['systemd-pstore'], 'ENABLE_PSTORE'],
|
||||||
['systemd-quotacheck.service',
|
['systemd-quotacheck.service',
|
||||||
|
|
|
@ -250,7 +250,8 @@
|
||||||
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
<citerefentry project='man-pages'><refentrytitle>objcopy</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
<citerefentry project='man-pages'><refentrytitle>objcopy</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd-creds</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd-creds</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-pcrphase.service</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
134
man/systemd-pcrphase.service.xml
Normal file
134
man/systemd-pcrphase.service.xml
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
|
||||||
|
|
||||||
|
<refentry id="systemd-pcrphase.service" conditional='HAVE_GNU_EFI'
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>systemd-pcrphase.service</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>systemd-pcrphase.service</refentrytitle>
|
||||||
|
<manvolnum>8</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>systemd-pcrphase.service</refname>
|
||||||
|
<refname>systemd-pcrphase-initrd.service</refname>
|
||||||
|
<refname>systemd-pcrphase</refname>
|
||||||
|
<refpurpose>Mark current boot process as successful</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<para><filename>systemd-pcrphase.service</filename></para>
|
||||||
|
<para><filename>systemd-pcrphase-initrd.service</filename></para>
|
||||||
|
<para><filename>/usr/lib/systemd/system-pcrphase</filename> <replaceable>STRING</replaceable></para>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><filename>systemd-pcrphase.service</filename> and
|
||||||
|
<filename>systemd-pcrphase-initrd.service</filename> are system services that measure specific strings
|
||||||
|
into TPM2 PCR 11 during boot.</para>
|
||||||
|
|
||||||
|
<para>These services require
|
||||||
|
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> to be
|
||||||
|
used in a unified kernel image (UKI) setup. They execute no operation when invoked when the stub has not
|
||||||
|
been used to invoke the kernel. The stub will measure the invoked kernel and associated vendor resources
|
||||||
|
into PCR 11 before handing control to it; once userspace is invoked these services then will extend
|
||||||
|
certain literal strings indicating various phases of the boot process into TPM2 PCR 11. During a regular
|
||||||
|
boot process the following strings are extended into PCR 11.</para>
|
||||||
|
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para><literal>enter-initrd</literal> is extended into PCR 11 early when the initrd
|
||||||
|
initializes, before activating system extension images for the initrd. It is supposed to act as barrier
|
||||||
|
between the time where the kernel initializes, and where the initrd starts operating and enables
|
||||||
|
system extension images, i.e. code shipped outside of the UKI. (This string is extended at start of
|
||||||
|
<filename>systemd-pcrphase-initrd.service</filename>.)</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para><literal>leave-initrd</literal> is extended into PCR 11 when the initrd is about to
|
||||||
|
transition into the host file system, i.e. when it achieved its purpose. It is supposed to act as
|
||||||
|
barrier between kernel/initrd code and host OS code. (This string is extended at stop of
|
||||||
|
<filename>systemd-pcrphase-initrd.service</filename>.)</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para><literal>ready</literal> is extended into PCR 11 during later boot-up, after remote
|
||||||
|
file systems have been activated (i.e. after <filename>remote-fs.target</filename>), but before users
|
||||||
|
are permitted to log in (i.e. before <filename>systemd-user-sessions.service</filename>). It is
|
||||||
|
supposed to act as barrier between the time where unprivileged regular users are still prohibited to
|
||||||
|
log in and where they are allowed to log in. (This string is extended at start of
|
||||||
|
<filename>systemd-pcrphase.service</filename>.)</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para><literal>shutdown</literal> is extended into PCR 11 during system shutdown. It is
|
||||||
|
supposed to act as barrier between the time the system is fully up and running and where it is about to
|
||||||
|
shut down. (This string is extended at stop of
|
||||||
|
<filename>systemd-pcrphase.service</filename>.)</para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
|
||||||
|
<para>During a regular system lifecycle, the strings <literal>enter-initrd</literal> →
|
||||||
|
<literal>leave-initrd</literal> → <literal>ready</literal> → <literal>shutdown</literal> are extended into
|
||||||
|
PCR 11, one after the other.</para>
|
||||||
|
|
||||||
|
<para>Specific phases of the boot process may be referenced via the series of strings measured, separated
|
||||||
|
by colons (the "boot path"). For example, the boot path for the regular system runtime is
|
||||||
|
<literal>enter-initrd:leave-initrd:ready</literal>, while the one for the initrd is just
|
||||||
|
<literal>enter-initrd</literal>. The boot path for the the boot phase before the initrd, is an empty
|
||||||
|
string; because that's hard to pass around a single colon (<literal>:</literal>) may be used
|
||||||
|
instead. Note that the aforementioned four strings are just the default strings and individual systems
|
||||||
|
might measure other strings at other times, and thus implement different and more fine-grained boot
|
||||||
|
phases to bind policy to.</para>
|
||||||
|
|
||||||
|
<para>By binding policy of TPM2 objects to a specific boot path it is possible to restrict access to them
|
||||||
|
to specific phases of the boot process, for example making it impossible to access the root file system's
|
||||||
|
encryption key after the system transitioned from the initrd into the host root file system.</para>
|
||||||
|
|
||||||
|
<para>Use
|
||||||
|
<citerefentry><refentrytitle>systemd-measure</refentrytitle><manvolnum>1</manvolnum></citerefentry> to
|
||||||
|
pre-calculate expected PCR 11 values for specific boot phases (via the <option>--phase=</option> switch).</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Options</title>
|
||||||
|
|
||||||
|
<para>The <filename>/usr/lib/systemd/system-pcrphase</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>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--bank=</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Takes the PCR banks to extend the specified word into. If not specified the tool
|
||||||
|
automatically determines all enabled PCR banks and measures the word into all of
|
||||||
|
them.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--tpm2-device=</option><replaceable>PATH</replaceable></term>
|
||||||
|
|
||||||
|
<listitem><para>Controls which TPM2 device to use. Expects a device node path referring to the TPM2
|
||||||
|
chip (e.g. <filename>/dev/tpmrm0</filename>). Alternatively the special value <literal>auto</literal>
|
||||||
|
may be specified, in order to automatically determine the device node of a suitable TPM2 device (of
|
||||||
|
which there must be exactly one). The special value <literal>list</literal> may be used to enumerate
|
||||||
|
all suitable TPM2 devices currently discovered.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<xi:include href="standard-options.xml" xpointer="help" />
|
||||||
|
<xi:include href="standard-options.xml" xpointer="version" />
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-measure</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
|
@ -2566,6 +2566,15 @@ if conf.get('HAVE_BLKID') == 1 and conf.get('HAVE_GNU_EFI') == 1
|
||||||
install_rpath : rootpkglibdir,
|
install_rpath : rootpkglibdir,
|
||||||
install : true,
|
install : true,
|
||||||
install_dir : rootlibexecdir)
|
install_dir : rootlibexecdir)
|
||||||
|
executable(
|
||||||
|
'systemd-pcrphase',
|
||||||
|
'src/boot/pcrphase.c',
|
||||||
|
include_directories : includes,
|
||||||
|
link_with : [libshared],
|
||||||
|
dependencies : [libopenssl, tpm2],
|
||||||
|
install_rpath : rootpkglibdir,
|
||||||
|
install : true,
|
||||||
|
install_dir : rootlibexecdir)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
262
src/boot/pcrphase.c
Normal file
262
src/boot/pcrphase.c
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include <sd-messages.h>
|
||||||
|
|
||||||
|
#include "efivars.h"
|
||||||
|
#include "main-func.h"
|
||||||
|
#include "openssl-util.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "pretty-print.h"
|
||||||
|
#include "tpm-pcr.h"
|
||||||
|
#include "tpm2-util.h"
|
||||||
|
|
||||||
|
static char *arg_tpm2_device = NULL;
|
||||||
|
static char **arg_banks = NULL;
|
||||||
|
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_banks, strv_freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
|
||||||
|
|
||||||
|
static int help(int argc, char *argv[], void *userdata) {
|
||||||
|
_cleanup_free_ char *link = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = terminal_urlify_man("systemd-pcrphase", "1", &link);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
printf("%1$s [OPTIONS...] COMMAND ...\n"
|
||||||
|
"\n%5$sMeasure boot phase into TPM2 PCR 11.%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"
|
||||||
|
" --tpm2-device=PATH Use specified TPM2 device\n"
|
||||||
|
"\nSee the %2$s for details.\n",
|
||||||
|
program_invocation_short_name,
|
||||||
|
link,
|
||||||
|
ansi_underline(),
|
||||||
|
ansi_normal(),
|
||||||
|
ansi_highlight(),
|
||||||
|
ansi_normal());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_argv(int argc, char *argv[]) {
|
||||||
|
enum {
|
||||||
|
ARG_VERSION = 0x100,
|
||||||
|
ARG_BANK,
|
||||||
|
ARG_TPM2_DEVICE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct option options[] = {
|
||||||
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
{ "version", no_argument, NULL, ARG_VERSION },
|
||||||
|
{ "bank", required_argument, NULL, ARG_BANK },
|
||||||
|
{ "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
int c;
|
||||||
|
|
||||||
|
assert(argc >= 0);
|
||||||
|
assert(argv);
|
||||||
|
|
||||||
|
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
||||||
|
switch (c) {
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
help(0, NULL, NULL);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case ARG_VERSION:
|
||||||
|
return version();
|
||||||
|
|
||||||
|
case ARG_BANK: {
|
||||||
|
const EVP_MD *implementation;
|
||||||
|
|
||||||
|
implementation = EVP_get_digestbyname(optarg);
|
||||||
|
if (!implementation)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", optarg);
|
||||||
|
|
||||||
|
if (strv_extend(&arg_banks, EVP_MD_name(implementation)) < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ARG_TPM2_DEVICE: {
|
||||||
|
_cleanup_free_ char *device = NULL;
|
||||||
|
|
||||||
|
if (streq(optarg, "list"))
|
||||||
|
return tpm2_list_devices();
|
||||||
|
|
||||||
|
if (!streq(optarg, "auto")) {
|
||||||
|
device = strdup(optarg);
|
||||||
|
if (!device)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
free_and_replace(arg_tpm2_device, device);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int determine_banks(struct tpm2_context *c) {
|
||||||
|
_cleanup_free_ TPMI_ALG_HASH *algs = NULL;
|
||||||
|
int n_algs, r;
|
||||||
|
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
if (!strv_isempty(arg_banks)) /* Explicitly configured? Then use that */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
n_algs = tpm2_get_good_pcr_banks(c->esys_context, UINT32_C(1) << TPM_PCR_INDEX_KERNEL_IMAGE, &algs);
|
||||||
|
if (n_algs <= 0)
|
||||||
|
return n_algs;
|
||||||
|
|
||||||
|
for (int i = 0; i < n_algs; i++) {
|
||||||
|
const EVP_MD *implementation;
|
||||||
|
const char *salg;
|
||||||
|
|
||||||
|
salg = tpm2_pcr_bank_to_string(algs[i]);
|
||||||
|
if (!salg)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure.");
|
||||||
|
|
||||||
|
implementation = EVP_get_digestbyname(salg);
|
||||||
|
if (!implementation)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unsupported PCR algorithm, can't measure.");
|
||||||
|
|
||||||
|
r = strv_extend(&arg_banks, EVP_MD_name(implementation));
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run(int argc, char *argv[]) {
|
||||||
|
_cleanup_(tpm2_context_destroy) struct tpm2_context c = {};
|
||||||
|
_cleanup_free_ char *joined = NULL, *pcr_string = NULL;
|
||||||
|
const char *word;
|
||||||
|
unsigned pcr_nr;
|
||||||
|
size_t length;
|
||||||
|
TSS2_RC rc;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
log_setup();
|
||||||
|
|
||||||
|
r = parse_argv(argc, argv);
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (optind+1 != argc)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected a single argument.");
|
||||||
|
|
||||||
|
word = argv[optind];
|
||||||
|
|
||||||
|
/* Refuse to measure an empty word. We want to be able to write the series of measured words
|
||||||
|
* separated by colons, where multiple separating colons are collapsed. Thus it makes sense to
|
||||||
|
* disallow an empty word to avoid ambiguities. */
|
||||||
|
if (isempty(word))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "String to measure cannot be empty, refusing.");
|
||||||
|
|
||||||
|
length = strlen(word);
|
||||||
|
|
||||||
|
/* Skip logic if sd-stub is not used, after all PCR 11 might have a very different purpose then. */
|
||||||
|
r = efi_get_variable_string(EFI_LOADER_VARIABLE(StubPcrKernelImage), &pcr_string);
|
||||||
|
if (r == -ENOENT) {
|
||||||
|
log_info("Kernel stub did not measure kernel image into PCR %u, skipping measurement.", TPM_PCR_INDEX_KERNEL_IMAGE);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to read StubPcrKernelImage EFI variable: %m");
|
||||||
|
|
||||||
|
/* Let's validate that the stub announced PCR 11 as we expected. */
|
||||||
|
r = safe_atou(pcr_string, &pcr_nr);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse StubPcrKernelImage EFI variable: %s", pcr_string);
|
||||||
|
if (pcr_nr != TPM_PCR_INDEX_KERNEL_IMAGE)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Kernel stub measured kernel image into PCR %u, which is different than expected %u.", pcr_nr, TPM_PCR_INDEX_KERNEL_IMAGE);
|
||||||
|
|
||||||
|
r = dlopen_tpm2();
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to load TPM2 libraries: %m");
|
||||||
|
|
||||||
|
r = tpm2_context_init(arg_tpm2_device, &c);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = determine_banks(&c);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (strv_isempty(arg_banks)) /* Still none? */
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Found a TPM2 without enabled PCR banks. Can't operate.");
|
||||||
|
|
||||||
|
TPML_DIGEST_VALUES values = {};
|
||||||
|
STRV_FOREACH(bank, arg_banks) {
|
||||||
|
const EVP_MD *implementation;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
assert_se(implementation = EVP_get_digestbyname(*bank));
|
||||||
|
|
||||||
|
if (values.count >= ELEMENTSOF(values.digests))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Too many banks selected.");
|
||||||
|
|
||||||
|
if ((size_t) EVP_MD_size(implementation) > sizeof(values.digests[values.count].digest))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Hash result too large for TPM2.");
|
||||||
|
|
||||||
|
id = tpm2_pcr_bank_from_string(EVP_MD_name(implementation));
|
||||||
|
if (id < 0)
|
||||||
|
return log_error_errno(id, "Can't map hash name to TPM2.");
|
||||||
|
|
||||||
|
values.digests[values.count].hashAlg = id;
|
||||||
|
|
||||||
|
if (EVP_Digest(word, length, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash word.");
|
||||||
|
|
||||||
|
values.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
joined = strv_join(arg_banks, ", ");
|
||||||
|
if (!joined)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
log_debug("Measuring '%s' into PCR index %u, banks %s.", word, TPM_PCR_INDEX_KERNEL_IMAGE, joined);
|
||||||
|
|
||||||
|
rc = sym_Esys_PCR_Extend(
|
||||||
|
c.esys_context,
|
||||||
|
ESYS_TR_PCR0 + TPM_PCR_INDEX_KERNEL_IMAGE, /* → PCR 11 */
|
||||||
|
ESYS_TR_PASSWORD,
|
||||||
|
ESYS_TR_NONE,
|
||||||
|
ESYS_TR_NONE,
|
||||||
|
&values);
|
||||||
|
if (rc != TSS2_RC_SUCCESS)
|
||||||
|
return log_error_errno(
|
||||||
|
SYNTHETIC_ERRNO(ENOTRECOVERABLE),
|
||||||
|
"Failed to measure '%s': %s",
|
||||||
|
word,
|
||||||
|
sym_Tss2_RC_Decode(rc));
|
||||||
|
|
||||||
|
log_struct(LOG_INFO,
|
||||||
|
"MESSAGE_ID=" SD_MESSAGE_TPM_PCR_EXTEND_STR,
|
||||||
|
LOG_MESSAGE("Successfully extended PCR index %u with '%s' (banks %s).", TPM_PCR_INDEX_KERNEL_IMAGE, word, joined),
|
||||||
|
"MEASURING=%s", word,
|
||||||
|
"PCR=%u", TPM_PCR_INDEX_KERNEL_IMAGE,
|
||||||
|
"BANKS=%s", joined);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_MAIN_FUNCTION(run);
|
|
@ -189,6 +189,9 @@ _SD_BEGIN_DECLARATIONS;
|
||||||
#define SD_MESSAGE_SHUTDOWN_CANCELED SD_ID128_MAKE(24,9f,6f,b9,e6,e2,42,8c,96,f3,f0,87,56,81,ff,a3)
|
#define SD_MESSAGE_SHUTDOWN_CANCELED SD_ID128_MAKE(24,9f,6f,b9,e6,e2,42,8c,96,f3,f0,87,56,81,ff,a3)
|
||||||
#define SD_MESSAGE_SHUTDOWN_CANCELED_STR SD_ID128_MAKE_STR(24,9f,6f,b9,e6,e2,42,8c,96,f3,f0,87,56,81,ff,a3)
|
#define SD_MESSAGE_SHUTDOWN_CANCELED_STR SD_ID128_MAKE_STR(24,9f,6f,b9,e6,e2,42,8c,96,f3,f0,87,56,81,ff,a3)
|
||||||
|
|
||||||
|
#define SD_MESSAGE_TPM_PCR_EXTEND SD_ID128_MAKE(3f,7d,5e,f3,e5,4f,43,02,b4,f0,b1,43,bb,27,0c,ab)
|
||||||
|
#define SD_MESSAGE_TPM_PCR_EXTEND_STR SD_ID128_MAKE_STR(3f,7d,5e,f3,e5,4f,43,02,b4,f0,b1,43,bb,27,0c,ab)
|
||||||
|
|
||||||
_SD_END_DECLARATIONS;
|
_SD_END_DECLARATIONS;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue