You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
5.0 KiB
118 lines
5.0 KiB
From 5db840e4bc7b86f7870c153d540ef0f6eddf64c2 Mon Sep 17 00:00:00 2001
|
|
From: Dan Streetman <ddstreet@ieee.org>
|
|
Date: Sun, 1 Jan 2023 23:42:09 -0500
|
|
Subject: [PATCH] tpm2: add tpm2_persist_handle()
|
|
|
|
Add function to convert a transient handle in the TPM into a persistent handle
|
|
in the TPM.
|
|
|
|
(cherry picked from commit d2d29c3be2ff9557d74c7bf852c1423ea6cfa25a)
|
|
|
|
Related: RHEL-16182
|
|
---
|
|
src/shared/tpm2-util.c | 83 +++++++++++++++++++++++++++++++++++++-----
|
|
1 file changed, 74 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
|
|
index c05c636745..0c5f3393dd 100644
|
|
--- a/src/shared/tpm2-util.c
|
|
+++ b/src/shared/tpm2-util.c
|
|
@@ -769,6 +769,75 @@ static int tpm2_esys_handle_from_tpm_handle(
|
|
return 1;
|
|
}
|
|
|
|
+/* Copy an object in the TPM at a transient location to a persistent location.
|
|
+ *
|
|
+ * The provided transient handle must exist in the TPM in the transient range. The persistent location may be
|
|
+ * 0 or any location in the persistent range. If 0, this will try each handle in the persistent range, in
|
|
+ * ascending order, until an available one is found. If non-zero, only the requested persistent location will
|
|
+ * be used.
|
|
+ *
|
|
+ * Returns 1 if the object was successfully persisted, or 0 if there is already a key at the requested
|
|
+ * location(s), or < 0 on error. The persistent handle is only provided when returning 1. */
|
|
+static int tpm2_persist_handle(
|
|
+ Tpm2Context *c,
|
|
+ const Tpm2Handle *transient_handle,
|
|
+ const Tpm2Handle *session,
|
|
+ TPMI_DH_PERSISTENT persistent_location,
|
|
+ Tpm2Handle **ret_persistent_handle) {
|
|
+
|
|
+ /* We don't use TPM2_PERSISTENT_FIRST and TPM2_PERSISTENT_LAST here due to:
|
|
+ * https://github.com/systemd/systemd/pull/27713#issuecomment-1591864753 */
|
|
+ TPMI_DH_PERSISTENT first = UINT32_C(0x81000000), last = UINT32_C(0x81ffffff);
|
|
+ TSS2_RC rc;
|
|
+ int r;
|
|
+
|
|
+ assert(c);
|
|
+ assert(transient_handle);
|
|
+
|
|
+ /* If persistent location specified, only try that. */
|
|
+ if (persistent_location != 0) {
|
|
+ if (TPM2_HANDLE_TYPE(persistent_location) != TPM2_HT_PERSISTENT)
|
|
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
+ "Handle not in persistent range: 0x%x", persistent_location);
|
|
+
|
|
+ first = last = persistent_location;
|
|
+ }
|
|
+
|
|
+ for (TPMI_DH_PERSISTENT requested = first; requested <= last; requested++) {
|
|
+ _cleanup_(tpm2_handle_freep) Tpm2Handle *persistent_handle = NULL;
|
|
+ r = tpm2_handle_new(c, &persistent_handle);
|
|
+ if (r < 0)
|
|
+ return r;
|
|
+
|
|
+ /* Since this is a persistent handle, don't flush it. */
|
|
+ persistent_handle->flush = false;
|
|
+
|
|
+ rc = sym_Esys_EvictControl(
|
|
+ c->esys_context,
|
|
+ ESYS_TR_RH_OWNER,
|
|
+ transient_handle->esys_handle,
|
|
+ session ? session->esys_handle : ESYS_TR_PASSWORD,
|
|
+ ESYS_TR_NONE,
|
|
+ ESYS_TR_NONE,
|
|
+ requested,
|
|
+ &persistent_handle->esys_handle);
|
|
+ if (rc == TSS2_RC_SUCCESS) {
|
|
+ if (ret_persistent_handle)
|
|
+ *ret_persistent_handle = TAKE_PTR(persistent_handle);
|
|
+
|
|
+ return 1;
|
|
+ }
|
|
+ if (rc != TPM2_RC_NV_DEFINED)
|
|
+ return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
|
|
+ "Failed to persist handle: %s", sym_Tss2_RC_Decode(rc));
|
|
+ }
|
|
+
|
|
+ if (ret_persistent_handle)
|
|
+ *ret_persistent_handle = NULL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
#define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
|
|
|
|
static int tpm2_credit_random(Tpm2Context *c) {
|
|
@@ -1203,16 +1272,12 @@ static int tpm2_make_primary(
|
|
FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - ts, USEC_PER_MSEC));
|
|
|
|
if (use_srk_model) {
|
|
- rc = sym_Esys_EvictControl(c->esys_context, ESYS_TR_RH_OWNER, primary->esys_handle,
|
|
- ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, TPM2_SRK_HANDLE, &primary->esys_handle);
|
|
- if (rc != TSS2_RC_SUCCESS)
|
|
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
|
|
- "Failed to persist SRK within TPM: %s", sym_Tss2_RC_Decode(rc));
|
|
- primary->flush = false;
|
|
- }
|
|
-
|
|
- if (ret_primary)
|
|
+ r = tpm2_persist_handle(c, primary, /* session= */ NULL, TPM2_SRK_HANDLE, ret_primary);
|
|
+ if (r < 0)
|
|
+ return r;
|
|
+ } else if (ret_primary)
|
|
*ret_primary = TAKE_PTR(primary);
|
|
+
|
|
if (ret_alg)
|
|
*ret_alg = alg;
|
|
|