]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2-util: gracefully skip deserialization when no input
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 8 Aug 2025 02:07:30 +0000 (11:07 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 3 Sep 2025 10:10:48 +0000 (12:10 +0200)
While at it, this also makes tpm2_deserialize() take struct iovec.

Fixes #38507.

(cherry picked from commit 8d40f3f42e04bf45d337e9b03d0750f3f34b92bb)

src/pcrlock/pcrlock.c
src/shared/tpm2-util.c
src/shared/tpm2-util.h

index b22d7a5ec417c7ee7605cc2fe28181ba45fa7342..94c80247768fb2d717456bda2ddaa27ac34fed85 100644 (file)
@@ -4520,15 +4520,13 @@ static int make_policy(bool force, RecoveryPinMode recovery_pin_mode) {
 
         _cleanup_(tpm2_handle_freep) Tpm2Handle *srk_handle = NULL;
 
-        if (iovec_is_set(&srk_blob)) {
-                r = tpm2_deserialize(
-                                tc,
-                                srk_blob.iov_base,
-                                srk_blob.iov_len,
-                                &srk_handle);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to deserialize SRK TR: %m");
-        } else {
+        r = tpm2_deserialize(
+                        tc,
+                        &srk_blob,
+                        &srk_handle);
+        if (r < 0)
+                return log_error_errno(r, "Failed to deserialize SRK TR: %m");
+        if (r == 0) {
                 r = tpm2_get_or_create_srk(
                                 tc,
                                 /* session= */ NULL,
@@ -4595,13 +4593,11 @@ static int make_policy(bool force, RecoveryPinMode recovery_pin_mode) {
         _cleanup_(tpm2_handle_freep) Tpm2Handle *nv_handle = NULL;
         TPM2_HANDLE nv_index = 0;
 
-        if (iovec_is_set(&nv_blob)) {
-                r = tpm2_deserialize(tc, nv_blob.iov_base, nv_blob.iov_len, &nv_handle);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to deserialize NV index TR: %m");
-
+        r = tpm2_deserialize(tc, &nv_blob, &nv_handle);
+        if (r < 0)
+                return log_error_errno(r, "Failed to deserialize NV index TR: %m");
+        if (r > 0)
                 nv_index = old_policy.nv_index;
-        }
 
         TPM2B_AUTH auth = {};
         CLEANUP_ERASE(auth);
@@ -4864,20 +4860,18 @@ static int undefine_policy_nv_index(
         _cleanup_(tpm2_handle_freep) Tpm2Handle *srk_handle = NULL;
         r = tpm2_deserialize(
                         tc,
-                        srk_blob->iov_base,
-                        srk_blob->iov_len,
+                        srk_blob,
                         &srk_handle);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to deserialize SRK TR: %m");
+        if (r < 0)
+                return log_error_errno(r, "Failed to deserialize SRK TR: %m");
 
         _cleanup_(tpm2_handle_freep) Tpm2Handle *nv_handle = NULL;
         r = tpm2_deserialize(
                         tc,
-                        nv_blob->iov_base,
-                        nv_blob->iov_len,
+                        nv_blob,
                         &nv_handle);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to deserialize NV TR: %m");
+        if (r < 0)
+                return log_error_errno(r, "Failed to deserialize NV TR: %m");
 
         _cleanup_(tpm2_handle_freep) Tpm2Handle *encryption_session = NULL;
         r = tpm2_make_encryption_session(
index 5b6b3ea93cd887491e732b4e53d69f14dd57d445..82a96a94f344fc2ff06b0b42b5833c3df669e75f 100644 (file)
@@ -4313,8 +4313,7 @@ static int tpm2_build_sealing_policy(
 
                 r = tpm2_deserialize(
                                 c,
-                                pcrlock_policy->nv_handle.iov_base,
-                                pcrlock_policy->nv_handle.iov_len,
+                                &pcrlock_policy->nv_handle,
                                 &nv_handle);
                 if (r < 0)
                         return r;
@@ -4754,17 +4753,20 @@ int tpm2_serialize(
 
 int tpm2_deserialize(
                 Tpm2Context *c,
-                const void *serialized,
-                size_t serialized_size,
+                const struct iovec *serialized,
                 Tpm2Handle **ret_handle) {
 
         TSS2_RC rc;
         int r;
 
         assert(c);
-        assert(serialized);
         assert(ret_handle);
 
+        if (!iovec_is_set(serialized)) {
+                *ret_handle = NULL;
+                return 0;
+        }
+
         _cleanup_(tpm2_handle_freep) Tpm2Handle *handle = NULL;
         r = tpm2_handle_new(c, &handle);
         if (r < 0)
@@ -4773,14 +4775,13 @@ int tpm2_deserialize(
         /* Since this is an existing handle in the TPM we should not implicitly flush it. */
         handle->flush = false;
 
-        rc = sym_Esys_TR_Deserialize(c->esys_context, serialized, serialized_size, &handle->esys_handle);
+        rc = sym_Esys_TR_Deserialize(c->esys_context, serialized->iov_base, serialized->iov_len, &handle->esys_handle);
         if (rc != TSS2_RC_SUCCESS)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                        "Failed to deserialize: %s", sym_Tss2_RC_Decode(rc));
 
         *ret_handle = TAKE_PTR(handle);
-
-        return 0;
+        return 1;
 }
 
 #if HAVE_OPENSSL
@@ -5697,11 +5698,13 @@ int tpm2_unseal(Tpm2Context *c,
         }
 
         _cleanup_(tpm2_handle_freep) Tpm2Handle *primary_handle = NULL;
-        if (iovec_is_set(srk)) {
-                r = tpm2_deserialize(c, srk->iov_base, srk->iov_len, &primary_handle);
-                if (r < 0)
-                        return r;
-        } else if (primary_alg != 0) {
+        r = tpm2_deserialize(c, srk, &primary_handle);
+        if (r < 0)
+                return r;
+        if (r == 0) {
+                if (primary_alg == 0)
+                        return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "No SRK or primary algorithm provided.");
+
                 TPM2B_PUBLIC template = {
                         .size = sizeof(TPMT_PUBLIC),
                 };
@@ -5718,9 +5721,7 @@ int tpm2_unseal(Tpm2Context *c,
                                 &primary_handle);
                 if (r < 0)
                         return r;
-        } else
-                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "No SRK or primary alg provided.");
+        }
 
         TPM2B_PUBLIC pubkey_tpm2b;
         _cleanup_(iovec_done) struct iovec fp = {};
index 77cd7dbcaf7e78effb935eabc1c9b8503e10ed5f..097f25ebaa7a81a2c3578b5cd27e6ccf7b5de7a6 100644 (file)
@@ -310,7 +310,7 @@ int tpm2_seal_data(Tpm2Context *c, const struct iovec *data, const Tpm2Handle *p
 int tpm2_unseal_data(Tpm2Context *c, const struct iovec *public, const struct iovec *private, const Tpm2Handle *primary_handle, const Tpm2Handle *policy_session, const Tpm2Handle *encryption_session, struct iovec *ret_data);
 
 int tpm2_serialize(Tpm2Context *c, const Tpm2Handle *handle, void **ret_serialized, size_t *ret_serialized_size);
-int tpm2_deserialize(Tpm2Context *c, const void *serialized, size_t serialized_size, Tpm2Handle **ret_handle);
+int tpm2_deserialize(Tpm2Context *c, const struct iovec *serialized, Tpm2Handle **ret_handle);
 
 int tpm2_load_public_key_file(const char *path, TPM2B_PUBLIC *ret);