mirror of
https://github.com/systemd/systemd.git
synced 2026-08-08 09:01:02 +00:00
tpm2-util: initialize NvPCRs on first extension
Both callers of tpm2_nvpcr_extend_bytes() duplicate the same dance: on -ENETDOWN, i.e. when the NvPCR isn't anchored yet because systemd-tpm2-setup hasn't run, they acquire the anchor secret, initialize the NvPCR, and extend again. Move this into tpm2_nvpcr_extend_bytes() itself. The only caller-specific bit, whether the anchor secret shall be synced to /var, is passed in as a parameter. Signed-off-by: Paul Meyer <katexochen0@gmail.com>
This commit is contained in:
@@ -1138,20 +1138,15 @@ static int measure_keyslot(
|
||||
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");
|
||||
|
||||
|
||||
@@ -373,23 +373,17 @@ static int extend_nvpcr_now(
|
||||
|
||||
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");
|
||||
|
||||
|
||||
@@ -8099,7 +8099,7 @@ int tpm2_nvpcr_get_index(const char *name, uint32_t *ret_nv_index, uint64_t *ret
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tpm2_nvpcr_extend_bytes(
|
||||
static int nvpcr_extend_bytes(
|
||||
Tpm2Context *c,
|
||||
const Tpm2Handle *session,
|
||||
const char *name,
|
||||
@@ -8211,6 +8211,37 @@ int tpm2_nvpcr_extend_bytes(
|
||||
#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,
|
||||
|
||||
@@ -194,7 +194,7 @@ int tpm2_pcr_extend_bytes(Tpm2Context *c, char **banks, unsigned pcr_index, cons
|
||||
#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);
|
||||
|
||||
Reference in New Issue
Block a user