if (!s)
return log_oom();
- r = tpm2_nvpcr_extend_bytes(c, /* session= */ NULL, arg_tpm2_measure_keyslot_nvpcr, &IOVEC_MAKE_STRING(s), /* secret= */ NULL, TPM2_EVENT_KEYSLOT, s);
- if (r == -ENETDOWN) {
- /* NvPCR is not initialized yet. Do so now. */
- _cleanup_(iovec_done_erase) struct iovec anchor_secret = {};
- r = tpm2_nvpcr_acquire_anchor_secret(&anchor_secret, /* sync_secondary= */ false);
- if (r < 0)
- return r;
-
- r = tpm2_nvpcr_initialize(c, /* session= */ NULL, arg_tpm2_measure_keyslot_nvpcr, &anchor_secret);
- if (r < 0)
- return log_error_errno(r, "Failed to extend NvPCR index '%s' with anchor secret: %m", name);
-
- r = tpm2_nvpcr_extend_bytes(c, /* session= */ NULL, arg_tpm2_measure_keyslot_nvpcr, &IOVEC_MAKE_STRING(s), /* secret= */ NULL, TPM2_EVENT_KEYSLOT, s);
- }
+ r = tpm2_nvpcr_extend_bytes(
+ c,
+ /* session= */ NULL,
+ arg_tpm2_measure_keyslot_nvpcr,
+ &IOVEC_MAKE_STRING(s),
+ /* secret= */ NULL,
+ /* sync_secondary_anchor= */ false,
+ TPM2_EVENT_KEYSLOT,
+ s);
if (r < 0)
return log_error_errno(r, "Could not extend NvPCR: %m");
log_debug("Measuring '%s' into NvPCR index '%s'.", safe, name);
- r = tpm2_nvpcr_extend_bytes(c, /* session= */ NULL, name, &IOVEC_MAKE(data, size), /* secret= */ NULL, event, safe);
- if (r == -ENETDOWN) {
- /* NvPCR is not initialized yet. Let's do this now. */
-
- _cleanup_(iovec_done_erase) struct iovec anchor_secret = {};
- r = tpm2_nvpcr_acquire_anchor_secret(&anchor_secret, /* sync_secondary= */ !arg_early);
- if (r < 0)
- return r;
-
- r = tpm2_nvpcr_initialize(c, /* session= */ NULL, name, &anchor_secret);
- if (r == -ENOBUFS)
- return r; /* NV space exhausted; let caller handle gracefully */
- if (r < 0)
- return log_error_errno(r, "Failed to extend NvPCR index '%s' with anchor secret: %m", name);
-
- r = tpm2_nvpcr_extend_bytes(c, /* session= */ NULL, name, &IOVEC_MAKE(data, size), /* secret= */ NULL, event, safe);
- }
+ r = tpm2_nvpcr_extend_bytes(
+ c,
+ /* session= */ NULL,
+ name,
+ &IOVEC_MAKE(data, size),
+ /* secret= */ NULL,
+ /* sync_secondary_anchor= */ !arg_early,
+ event,
+ safe);
+ if (r == -ENOBUFS)
+ return r; /* NV space exhausted; let caller handle gracefully */
if (r < 0)
return log_error_errno(r, "Could not extend NvPCR: %m");
return 0;
}
-int tpm2_nvpcr_extend_bytes(
+static int nvpcr_extend_bytes(
Tpm2Context *c,
const Tpm2Handle *session,
const char *name,
#endif
}
+int tpm2_nvpcr_extend_bytes(
+ Tpm2Context *c,
+ const Tpm2Handle *session,
+ const char *name,
+ const struct iovec *data,
+ const struct iovec *secret,
+ bool sync_secondary_anchor,
+ Tpm2UserspaceEventType event_type,
+ const char *description) {
+
+ int r;
+
+ r = nvpcr_extend_bytes(c, session, name, data, secret, event_type, description);
+ if (r != -ENETDOWN)
+ return r;
+
+ /* The NvPCR isn't anchored yet, i.e. systemd-tpm2-setup hasn't run.
+ * Anchor it now and extend again. */
+
+ _cleanup_(iovec_done_erase) struct iovec anchor_secret = {};
+ r = tpm2_nvpcr_acquire_anchor_secret(&anchor_secret, sync_secondary_anchor);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to acquire anchor secret for NvPCR '%s': %m", name);
+
+ r = tpm2_nvpcr_initialize(c, session, name, &anchor_secret);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to initialize NvPCR '%s' with anchor secret: %m", name);
+
+ return nvpcr_extend_bytes(c, session, name, data, secret, event_type, description);
+}
+
#if HAVE_OPENSSL
static int tpm2_nvpcr_write_anchor_secret(
const char *dir,
#define TPM2_NVPCR_PRIORITY_DEFAULT UINT64_C(1000)
int tpm2_nvpcr_get_index(const char *name, uint32_t *ret_nv_index, uint64_t *ret_priority);
-int tpm2_nvpcr_extend_bytes(Tpm2Context *c, const Tpm2Handle *session, const char *name, const struct iovec *data, const struct iovec *secret, Tpm2UserspaceEventType event_type, const char *description);
+int tpm2_nvpcr_extend_bytes(Tpm2Context *c, const Tpm2Handle *session, const char *name, const struct iovec *data, const struct iovec *secret, bool sync_secondary_anchor, Tpm2UserspaceEventType event_type, const char *description);
int tpm2_nvpcr_acquire_anchor_secret(struct iovec *ret, bool sync_secondary);
int tpm2_nvpcr_initialize(Tpm2Context *c, const Tpm2Handle *session, const char *name, const struct iovec *anchor_secret);
int tpm2_nvpcr_read(Tpm2Context *c, const Tpm2Handle *session, const char *name, struct iovec *ret, uint32_t *ret_nv_index, uint64_t *ret_priority);