]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2-util: introduce tpm2b_sensitive_data_erase_and_esys_freep() destructor 34177/head
authorLennart Poettering <lennart@poettering.net>
Thu, 5 Sep 2024 16:29:26 +0000 (18:29 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 6 Sep 2024 13:55:28 +0000 (15:55 +0200)
Let's make sure we erase TPM2B_SENSITIVE_DATA structures reliably in all
code paths.

src/shared/tpm2-util.c

index b93b744d8b7cf02f8c409f66f46b652463bbbd34..263acb8f9e785215a0485b7c2a7a185a34be49a1 100644 (file)
@@ -210,10 +210,22 @@ int dlopen_tpm2(void) {
 }
 
 void Esys_Freep(void *p) {
+        assert(p);
+
         if (*(void**) p)
                 sym_Esys_Free(*(void**) p);
 }
 
+static void tpm2b_sensitive_data_erase_and_esys_freep(TPM2B_SENSITIVE_DATA **p) {
+        assert(p);
+
+        if (!*p)
+                return;
+
+        explicit_bzero_safe((*p)->buffer, (*p)->size);
+        sym_Esys_Free(*p);
+}
+
 /* Get a specific TPM capability (or capabilities).
  *
  * Returns 0 if there are no more capability properties of the requested type, or 1 if there are more, or < 0
@@ -5804,7 +5816,7 @@ int tpm2_unseal(Tpm2Context *c,
 
                         log_debug("Unsealing HMAC key for shard %zu.", shard);
 
-                        _cleanup_(Esys_Freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
+                        _cleanup_(tpm2b_sensitive_data_erase_and_esys_freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
                         rc = sym_Esys_Unseal(
                                         c->esys_context,
                                         hmac_key->esys_handle,
@@ -5823,8 +5835,6 @@ int tpm2_unseal(Tpm2Context *c,
 
                         if (!iovec_append(&secret, &IOVEC_MAKE(unsealed->buffer, unsealed->size)))
                                 return log_oom_debug();
-
-                        explicit_bzero_safe(unsealed->buffer, unsealed->size);
                 }
 
                 if (!retry)
@@ -6105,7 +6115,7 @@ int tpm2_unseal_data(
         if (r < 0)
                 return r;
 
-        _cleanup_(Esys_Freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
+        _cleanup_(tpm2b_sensitive_data_erase_and_esys_freep) TPM2B_SENSITIVE_DATA* unsealed = NULL;
         rc = sym_Esys_Unseal(
                         c->esys_context,
                         what->esys_handle,
@@ -6120,11 +6130,10 @@ int tpm2_unseal_data(
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                        "Failed to unseal data: %s", sym_Tss2_RC_Decode(rc));
 
-        _cleanup_(iovec_done) struct iovec d = {};
-        d = IOVEC_MAKE(memdup(unsealed->buffer, unsealed->size), unsealed->size);
-
-        explicit_bzero_safe(unsealed->buffer, unsealed->size);
-
+        _cleanup_(iovec_done) struct iovec d = {
+                .iov_base = memdup(unsealed->buffer, unsealed->size),
+                .iov_len = unsealed->size,
+        };
         if (!d.iov_base)
                 return log_oom_debug();