pcrextend: make PCR index configurable

Let's make the tool a tiny bit more generic by allowing the PCR index to
measure into to be configurable.
This commit is contained in:
Lennart Poettering 2023-09-25 10:51:56 +02:00
parent 32295fa08f
commit b0d00ec60a
2 changed files with 33 additions and 10 deletions

View file

@ -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>

View file

@ -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);
@ -46,7 +48,8 @@ static int help(int argc, char *argv[], void *userdata) {
"\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;