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.
183 lines
6.9 KiB
183 lines
6.9 KiB
8 months ago
|
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,
|