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.
82 lines
4.0 KiB
82 lines
4.0 KiB
8 months ago
|
From 7b0f212fe888bd03917de131ead35c4109cc723a Mon Sep 17 00:00:00 2001
|
||
|
From: Dan Streetman <ddstreet@ieee.org>
|
||
|
Date: Fri, 21 Jul 2023 11:23:22 -0400
|
||
|
Subject: [PATCH] tpm2: instead of adjusting authValue trailing 0(s), trim them
|
||
|
as required by tpm spec
|
||
|
|
||
|
To keep compatibility with any existing object authValues with trailing 0's,
|
||
|
change tpm2_get_pin_auth() to trim trailing 0's, which is what the TPM
|
||
|
implementation will do. This should retain compatibility with any existing
|
||
|
authValues that contain trailing 0's.
|
||
|
|
||
|
Note that any existing authValues with trailing 0's are unlikely to have worked
|
||
|
in the way that systemd uses them in object sealing, which is as a bind key for
|
||
|
the encryption (and policy) session. However, it is better to be compatible
|
||
|
with the TPM spec (and implementations) even if previously created objects that
|
||
|
are affected may not have worked.
|
||
|
|
||
|
Fixes: #28414
|
||
|
(cherry picked from commit 63477a71dfa39f0cb43854cb28df6606733063ef)
|
||
|
|
||
|
Related: RHEL-16182
|
||
|
---
|
||
|
src/shared/tpm2-util.c | 38 +++++++++++++++++++++++++++++++-------
|
||
|
1 file changed, 31 insertions(+), 7 deletions(-)
|
||
|
|
||
|
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
|
||
|
index 49e50a83ac..5bce39a994 100644
|
||
|
--- a/src/shared/tpm2-util.c
|
||
|
+++ b/src/shared/tpm2-util.c
|
||
|
@@ -2799,8 +2799,36 @@ int tpm2_digest_many_digests(
|
||
|
* 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. */
|
||
|
+ * digest that randomly happens to end in 0 must have the final 0(s) trimmed.
|
||
|
+ *
|
||
|
+ * This is required at 2 points. First, when setting the authValue during creation of new sealed objects, in
|
||
|
+ * tpm2_seal(). This only applies to newly created objects, of course. Second, when using a previously
|
||
|
+ * created sealed object that has an authValue set, we use the sealed objects as the session bind key. This
|
||
|
+ * requires calling SetAuth so tpm2-tss can correctly calculate the HMAC to use for the encryption session.
|
||
|
+ *
|
||
|
+ * TPM implementations will perform the trimming for any authValue for existing sealed objects, so the
|
||
|
+ * tpm2-tss library must also perform the trimming before HMAC calculation, but it does not yet; this bug is
|
||
|
+ * open to add the trimming: https://github.com/tpm2-software/tpm2-tss/issues/2664
|
||
|
+ *
|
||
|
+ * Until our minimum tpm2-tss version contains a fix for that bug, we must perform the trimming
|
||
|
+ * ourselves. Note that since we are trimming, which is exactly what a TPM implementation would do, this will
|
||
|
+ * work for both existing objects with a authValue ending in 0(s) as well as new sealed objects we create,
|
||
|
+ * which we will trim the 0(s) from before sending to the TPM.
|
||
|
+ */
|
||
|
+static void tpm2_trim_auth_value(TPM2B_AUTH *auth) {
|
||
|
+ bool trimmed = false;
|
||
|
+
|
||
|
+ assert(auth);
|
||
|
+
|
||
|
+ while (auth->size > 0 && auth->buffer[auth->size - 1] == 0) {
|
||
|
+ trimmed = true;
|
||
|
+ auth->size--;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (trimmed)
|
||
|
+ log_debug("authValue ends in 0, trimming as required by the TPM2 specification Part 1 section 'HMAC Computation' authValue Note 2.");
|
||
|
+}
|
||
|
+
|
||
|
static int tpm2_get_pin_auth(TPMI_ALG_HASH hash, const char *pin, TPM2B_AUTH *ret_auth) {
|
||
|
TPM2B_AUTH auth = {};
|
||
|
int r;
|
||
|
@@ -2812,11 +2840,7 @@ static int tpm2_get_pin_auth(TPMI_ALG_HASH hash, const char *pin, TPM2B_AUTH *re
|
||
|
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;
|
||
|
- }
|
||
|
+ tpm2_trim_auth_value(&auth);
|
||
|
|
||
|
*ret_auth = TAKE_STRUCT(auth);
|
||
|
|