]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pcrextend: make PCR index configurable
authorLennart Poettering <lennart@poettering.net>
Mon, 25 Sep 2023 08:51:56 +0000 (10:51 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 25 Sep 2023 15:17:20 +0000 (17:17 +0200)
Let's make the tool a tiny bit more generic by allowing the PCR index to
measure into to be configurable.

man/systemd-pcrphase.service.xml
src/pcrextend/pcrextend.c

index 93d27019cb9e7b791862398ff6f8be3d203430cc..807317a7de7a0aa75967e48210c54a125e7d230b 100644 (file)
         <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>
 
index 74021374d3253120f4208737fecba72d41808347..358bee72b081614c181ceabf65cc68d0f927d47b 100644 (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;