diff --git a/man/veritytab.xml b/man/veritytab.xml
index 9b131e350c..913acad9a2 100644
--- a/man/veritytab.xml
+++ b/man/veritytab.xml
@@ -298,6 +298,18 @@ This is based on crypttab(5).
+
+
+
+ Takes a boolean argument, or an NvPCR name as argument. May be used to enable
+ automatic measurement of the volume name and Verity root hash, as well as the serials and issuers of
+ the certificates used to generate the provided signatures (if any) will be measured. Passing false
+ disables the mechanism. Passing true enables measurement into the verity NvPCR. If
+ any other string is specified this selects the NvPCR to measure into by name.
+
+
+
+
At early boot and when the system manager configuration is
diff --git a/src/veritysetup/veritysetup.c b/src/veritysetup/veritysetup.c
index 91b5bcaaa2..e2135562c1 100644
--- a/src/veritysetup/veritysetup.c
+++ b/src/veritysetup/veritysetup.c
@@ -16,9 +16,11 @@
#include "main-func.h"
#include "parse-util.h"
#include "path-util.h"
+#include "pcrextend-util.h"
#include "pretty-print.h"
#include "string-util.h"
#include "strv.h"
+#include "tpm2-util.h"
#include "verbs.h"
static char *arg_hash = NULL; /* the hash algorithm */
@@ -38,12 +40,14 @@ static uint64_t arg_fec_roots = 2;
static void *arg_root_hash_signature = NULL;
static size_t arg_root_hash_signature_size = 0;
static bool arg_root_hash_signature_auto = false;
+static char *arg_tpm2_measure_nvpcr = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_hash, freep);
STATIC_DESTRUCTOR_REGISTER(arg_salt, freep);
STATIC_DESTRUCTOR_REGISTER(arg_uuid, freep);
STATIC_DESTRUCTOR_REGISTER(arg_fec_what, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root_hash_signature, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_tpm2_measure_nvpcr, freep);
static int help(void) {
_cleanup_free_ char *link = NULL;
@@ -142,7 +146,7 @@ static int parse_options(const char *options) {
for (;;) {
_cleanup_free_ char *word = NULL;
- char *val;
+ const char *val;
r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
if (r < 0)
@@ -290,6 +294,21 @@ static int parse_options(const char *options) {
if (r < 0)
return r;
+ } else if ((val = startswith(word, "tpm2-measure-nvpcr="))) {
+ r = isempty(val) ? 0 : parse_boolean(val);
+ if (r == 0) {
+ arg_tpm2_measure_nvpcr = mfree(arg_tpm2_measure_nvpcr);
+ return 0;
+ }
+ if (r > 0)
+ val = "verity";
+ else if (!tpm2_nvpcr_name_is_valid(val)) {
+ log_warning("Invalid NvPCR name, ignoring: %s", word);
+ return 0;
+ }
+
+ if (free_and_strdup(&arg_tpm2_measure_nvpcr, val) < 0)
+ return log_oom();
} else
log_warning("Encountered unknown option '%s', ignoring.", word);
}
@@ -423,6 +442,11 @@ static int verb_attach(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to set up verity device '%s': %m", volume);
+ (void) pcrextend_verity_now(
+ volume,
+ &IOVEC_MAKE(rh, rh_size),
+ &IOVEC_MAKE(arg_root_hash_signature, arg_root_hash_signature_size));
+
return 0;
}