From: Yu Watanabe Date: Fri, 8 Aug 2025 02:07:30 +0000 (+0900) Subject: tpm2-util: gracefully skip deserialization when no input X-Git-Tag: v257.9~48 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=944dc1af4ddbd89a339be8dcf169abea8a5a05d1;p=thirdparty%2Fsystemd.git tpm2-util: gracefully skip deserialization when no input While at it, this also makes tpm2_deserialize() take struct iovec. Fixes #38507. (cherry picked from commit 8d40f3f42e04bf45d337e9b03d0750f3f34b92bb) --- diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index b22d7a5ec41..94c80247768 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -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( diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 5b6b3ea93cd..82a96a94f34 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -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 = {}; diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 77cd7dbcaf7..097f25ebaa7 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -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);