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.
systemd/SOURCES/0508-tpm2-add-tpm2_get_poli...

183 lines
6.9 KiB

From ba5a271dbb71edc1985b7d9f837d7904ad2a4529 Mon Sep 17 00:00:00 2001
From: Dan Streetman <ddstreet@ieee.org>
Date: Fri, 16 Dec 2022 16:33:08 -0500
Subject: [PATCH] tpm2: add tpm2_get_policy_digest()
(cherry picked from commit 23b972d571650014ab5f22610da80a62f53f2245)
Related: RHEL-16182
---
src/shared/tpm2-util.c | 99 ++++++++++++++++++++++++------------------
1 file changed, 57 insertions(+), 42 deletions(-)
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
index c22a200a5c..b5eabb8159 100644
--- a/src/shared/tpm2-util.c
+++ b/src/shared/tpm2-util.c
@@ -476,6 +476,54 @@ void tpm2_pcr_mask_to_selection(uint32_t mask, uint16_t bank, TPML_PCR_SELECTION
};
}
+static void tpm2_log_debug_buffer(const void *buffer, size_t size, const char *msg) {
+ if (!DEBUG_LOGGING || !buffer || size == 0)
+ return;
+
+ _cleanup_free_ char *h = hexmem(buffer, size);
+ log_debug("%s: %s", msg ?: "Buffer", strna(h));
+}
+
+static void tpm2_log_debug_digest(const TPM2B_DIGEST *digest, const char *msg) {
+ if (digest)
+ tpm2_log_debug_buffer(digest->buffer, digest->size, msg ?: "Digest");
+}
+
+static int tpm2_get_policy_digest(
+ Tpm2Context *c,
+ const Tpm2Handle *session,
+ TPM2B_DIGEST **ret_policy_digest) {
+
+ TSS2_RC rc;
+
+ if (!DEBUG_LOGGING && !ret_policy_digest)
+ return 0;
+
+ assert(c);
+ assert(session);
+
+ log_debug("Acquiring policy digest.");
+
+ _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
+ rc = sym_Esys_PolicyGetDigest(
+ c->esys_context,
+ session->esys_handle,
+ ESYS_TR_NONE,
+ ESYS_TR_NONE,
+ ESYS_TR_NONE,
+ &policy_digest);
+ if (rc != TSS2_RC_SUCCESS)
+ return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
+ "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
+
+ tpm2_log_debug_digest(policy_digest, "Session policy digest");
+
+ if (ret_policy_digest)
+ *ret_policy_digest = TAKE_PTR(policy_digest);
+
+ return 0;
+}
+
static unsigned find_nth_bit(uint32_t mask, unsigned n) {
uint32_t bit = 1;
@@ -1100,7 +1148,6 @@ static int tpm2_make_policy_session(
.keyBits.aes = 128,
.mode.aes = TPM2_ALG_CFB,
};
- _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
TSS2_RC rc;
int r;
@@ -1237,16 +1284,9 @@ static int tpm2_make_policy_session(
/* Get the policy hash of the PCR policy */
_cleanup_(Esys_Freep) TPM2B_DIGEST *approved_policy = NULL;
- rc = sym_Esys_PolicyGetDigest(
- c->esys_context,
- session->esys_handle,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- &approved_policy);
- if (rc != TSS2_RC_SUCCESS)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
+ r = tpm2_get_policy_digest(c, session, &approved_policy);
+ if (r < 0)
+ return r;
/* When we are unlocking and have a signature, let's pass it to the TPM */
_cleanup_(Esys_Freep) TPMT_TK_VERIFIED *check_ticket_buffer = NULL;
@@ -1361,38 +1401,13 @@ static int tpm2_make_policy_session(
sym_Tss2_RC_Decode(rc));
}
- if (DEBUG_LOGGING || ret_policy_digest) {
- log_debug("Acquiring policy digest.");
-
- rc = sym_Esys_PolicyGetDigest(
- c->esys_context,
- session->esys_handle,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- ESYS_TR_NONE,
- &policy_digest);
-
- if (rc != TSS2_RC_SUCCESS)
- return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
- "Failed to get policy digest from TPM: %s", sym_Tss2_RC_Decode(rc));
-
- if (DEBUG_LOGGING) {
- _cleanup_free_ char *h = NULL;
-
- h = hexmem(policy_digest->buffer, policy_digest->size);
- if (!h)
- return log_oom();
-
- log_debug("Session policy digest: %s", h);
- }
- }
+ r = tpm2_get_policy_digest(c, session, ret_policy_digest);
+ if (r < 0)
+ return r;
if (ret_session)
*ret_session = TAKE_PTR(session);
- if (ret_policy_digest)
- *ret_policy_digest = TAKE_PTR(policy_digest);
-
if (ret_pcr_bank)
*ret_pcr_bank = pcr_bank;
@@ -1414,7 +1429,6 @@ int tpm2_seal(const char *device,
uint16_t *ret_pcr_bank,
uint16_t *ret_primary_alg) {
- _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
_cleanup_(Esys_Freep) TPM2B_PRIVATE *private = NULL;
_cleanup_(Esys_Freep) TPM2B_PUBLIC *public = NULL;
static const TPML_PCR_SELECTION creation_pcr = {};
@@ -1423,7 +1437,6 @@ int tpm2_seal(const char *device,
TPM2B_SENSITIVE_CREATE hmac_sensitive;
TPMI_ALG_PUBLIC primary_alg;
TPM2B_PUBLIC hmac_template;
- TPMI_ALG_HASH pcr_bank;
usec_t start;
TSS2_RC rc;
int r;
@@ -1477,6 +1490,8 @@ int tpm2_seal(const char *device,
if (r < 0)
return r;
+ _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
+ TPMI_ALG_HASH pcr_bank;
r = tpm2_make_policy_session(
c,
primary,
@@ -1608,7 +1623,6 @@ int tpm2_unseal(const char *device,
size_t *ret_secret_size) {
_cleanup_(Esys_Freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
- _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
_cleanup_(erase_and_freep) char *secret = NULL;
TPM2B_PRIVATE private = {};
TPM2B_PUBLIC public = {};
@@ -1708,6 +1722,7 @@ int tpm2_unseal(const char *device,
for (unsigned i = RETRY_UNSEAL_MAX;; i--) {
_cleanup_tpm2_handle_ Tpm2Handle *policy_session = NULL;
+ _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
r = tpm2_make_policy_session(
c,
primary,