analyze: add "srk" verb to extract current srk from TPM2 chip

This is pretty low-level functionality, hence placed in systemd-analyze.
This is useful for working with systemd-cryptenroll --tpm2-device-key=,
as it acquires the SRK without requiring the full tpm2-tss tool set.
This commit is contained in:
Lennart Poettering 2023-11-08 22:34:24 +01:00
parent fbe7db47f4
commit d30693f39b
5 changed files with 70 additions and 0 deletions

View file

@ -174,6 +174,11 @@
<arg choice="plain">pcrs</arg>
<arg choice="opt" rep="repeat"><replaceable>PCR</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-analyze</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">srk</arg> &gt;<arg choice="plain"><replaceable>FILE</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
@ -926,6 +931,16 @@ NR NAME SHA256
23 application-support 0000000000000000000000000000000000000000000000000000000000000000</programlisting>
</example>
</refsect2>
<refsect2>
<title><command>systemd-analyze srk &gt; <replaceable>FILE</replaceable></command></title>
<para>This command reads the Storage Root Key (SRK) from the TPM2 device, and writes it in marshalled
TPM2B_PUBLIC format to stdout. Example:</para>
<programlisting>systemd-analyze srk &gt; srk.tpm2b_public</programlisting>
</refsect2>
</refsect1>
<refsect1>

47
src/analyze/analyze-srk.c Normal file
View file

@ -0,0 +1,47 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "analyze.h"
#include "analyze-srk.h"
#include "tpm2-util.h"
int verb_srk(int argc, char *argv[], void *userdata) {
#if HAVE_TPM2
_cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
_cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
int r;
r = tpm2_context_new(/* device= */ NULL, &c);
if (r < 0)
return log_error_errno(r, "Failed to create TPM2 context: %m");
r = tpm2_get_srk(
c,
/* session= */ NULL,
&public,
/* ret_name= */ NULL,
/* ret_qname= */ NULL,
/* ret_handle= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to get SRK: %m");
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "No SRK stored so far.");
_cleanup_free_ void *marshalled = NULL;
size_t marshalled_size = 0;
r = tpm2_marshal_public(public, &marshalled, &marshalled_size);
if (r < 0)
return log_error_errno(r, "Failed to marshal SRK: %m");
if (isatty(STDOUT_FILENO))
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Refusing to write binary data to TTY, please redirect output to file.");
if (fwrite(marshalled, 1, marshalled_size, stdout) != marshalled_size)
return log_error_errno(errno, "Failed to write SRK to stdout: %m");
fflush(stdout);
return EXIT_SUCCESS;
#else
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support not available.");
#endif
}

View file

@ -0,0 +1,4 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
int verb_srk(int argc, char *argv[], void *userdata);

View file

@ -32,6 +32,7 @@
#include "analyze-plot.h"
#include "analyze-security.h"
#include "analyze-service-watchdogs.h"
#include "analyze-srk.h"
#include "analyze-syscall-filter.h"
#include "analyze-time.h"
#include "analyze-time-data.h"
@ -236,6 +237,7 @@ static int help(int argc, char *argv[], void *userdata) {
" malloc [D-BUS SERVICE...] Dump malloc stats of a D-Bus service\n"
" fdstore SERVICE... Show file descriptor store contents of service\n"
" pcrs [PCR...] Show TPM2 PCRs and their names\n"
" srk > FILE Write TPM2 SRK to stdout\n"
"\nOptions:\n"
" --recursive-errors=MODE Control which units are verified\n"
" --offline=BOOL Perform a security review on unit file(s)\n"
@ -646,6 +648,7 @@ static int run(int argc, char *argv[]) {
{ "fdstore", 2, VERB_ANY, 0, verb_fdstore },
{ "image-policy", 2, 2, 0, verb_image_policy },
{ "pcrs", VERB_ANY, VERB_ANY, 0, verb_pcrs },
{ "srk", VERB_ANY, 1, 0, verb_srk },
{}
};

View file

@ -21,6 +21,7 @@ systemd_analyze_sources = files(
'analyze-plot.c',
'analyze-security.c',
'analyze-service-watchdogs.c',
'analyze-srk.c',
'analyze-syscall-filter.c',
'analyze-time.c',
'analyze-time-data.c',