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.
75 lines
3.0 KiB
75 lines
3.0 KiB
From fd901d06e52786cfb2bd67919c72d05eab5a4c65 Mon Sep 17 00:00:00 2001
|
|
From: Dan Streetman <ddstreet@ieee.org>
|
|
Date: Sat, 15 Jul 2023 08:30:40 -0400
|
|
Subject: [PATCH] tpm2: add tpm2_get_pin_auth()
|
|
|
|
Add function to calculate the hash digest for a provided pin, and also verify
|
|
that the final byte in the digest is not 0. This is required because the TPM
|
|
will always remove all trailing 0's from an auth value before using it.
|
|
|
|
Fixes: #27716
|
|
(cherry picked from commit f230572f56a34fd7269c5fda4fb92be5ee0ea281)
|
|
|
|
Related: RHEL-16182
|
|
---
|
|
src/shared/tpm2-util.c | 32 ++++++++++++++++++++++++++++++--
|
|
1 file changed, 30 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
|
|
index cb05b2a01c..49e50a83ac 100644
|
|
--- a/src/shared/tpm2-util.c
|
|
+++ b/src/shared/tpm2-util.c
|
|
@@ -2795,6 +2795,34 @@ int tpm2_digest_many_digests(
|
|
return tpm2_digest_many(alg, digest, iovecs, n_data, extend);
|
|
}
|
|
|
|
+/* This hashes the provided pin into a digest value, but also verifies that the final byte is not 0, because
|
|
+ * the TPM specification Part 1 ("Architecture") section Authorization Values (subsection "Authorization Size
|
|
+ * Convention") states "Trailing octets of zero are to be removed from any string before it is used as an
|
|
+ * authValue". Since the TPM doesn't know if the auth value is a "string" or just a hash digest, any hash
|
|
+ * digest that randomly happens to end in 0 must have the final 0 changed, or the TPM will remove it before
|
|
+ * using the value in its HMAC calculations, resulting in failed HMAC checks. */
|
|
+static int tpm2_get_pin_auth(TPMI_ALG_HASH hash, const char *pin, TPM2B_AUTH *ret_auth) {
|
|
+ TPM2B_AUTH auth = {};
|
|
+ int r;
|
|
+
|
|
+ assert(pin);
|
|
+ assert(ret_auth);
|
|
+
|
|
+ r = tpm2_digest_buffer(hash, &auth, pin, strlen(pin), /* extend= */ false);
|
|
+ if (r < 0)
|
|
+ return r;
|
|
+
|
|
+ assert(auth.size > 0);
|
|
+ if (auth.buffer[auth.size - 1] == 0) {
|
|
+ log_debug("authValue digest ends in 0 which the TPM will remove and cause HMAC authorization failures, adjusting.");
|
|
+ auth.buffer[auth.size - 1] = 0xff;
|
|
+ }
|
|
+
|
|
+ *ret_auth = TAKE_STRUCT(auth);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int tpm2_set_auth(Tpm2Context *c, const Tpm2Handle *handle, const char *pin) {
|
|
TPM2B_AUTH auth = {};
|
|
TSS2_RC rc;
|
|
@@ -2808,7 +2836,7 @@ static int tpm2_set_auth(Tpm2Context *c, const Tpm2Handle *handle, const char *p
|
|
|
|
CLEANUP_ERASE(auth);
|
|
|
|
- r = tpm2_digest_buffer(TPM2_ALG_SHA256, &auth, pin, strlen(pin), /* extend= */ false);
|
|
+ r = tpm2_get_pin_auth(TPM2_ALG_SHA256, pin, &auth);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
@@ -3955,7 +3983,7 @@ int tpm2_seal(Tpm2Context *c,
|
|
CLEANUP_ERASE(hmac_sensitive);
|
|
|
|
if (pin) {
|
|
- r = tpm2_digest_buffer(TPM2_ALG_SHA256, &hmac_sensitive.userAuth, pin, strlen(pin), /* extend= */ false);
|
|
+ r = tpm2_get_pin_auth(TPM2_ALG_SHA256, pin, &hmac_sensitive.userAuth);
|
|
if (r < 0)
|
|
return r;
|
|
}
|