]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2-util: credit TPM2 RNG entropy only once per boot
authorLennart Poettering <lennart@poettering.net>
Wed, 17 Aug 2022 07:51:35 +0000 (09:51 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 17 Aug 2022 12:58:17 +0000 (21:58 +0900)
Acquiring random data from the TPM is not precisely quick, let's speed
things up by doing this at most once per boot. For that, let's maintain
a flag file in /run/.

src/shared/tpm2-util.c

index 33703c4aa3bf908d1c0bbc620ff46c7c6d026f81..1f099bcf17a19c9d78525bd0398802b7957785d7 100644 (file)
@@ -225,9 +225,12 @@ static int tpm2_init(const char *device, struct tpm2_context *ret) {
         return 0;
 }
 
+#define TPM2_CREDIT_RANDOM_FLAG_PATH "/run/systemd/tpm-rng-credited"
+
 static int tpm2_credit_random(ESYS_CONTEXT *c) {
         size_t rps, done = 0;
         TSS2_RC rc;
+        usec_t t;
         int r;
 
         assert(c);
@@ -237,6 +240,16 @@ static int tpm2_credit_random(ESYS_CONTEXT *c) {
          * but likely better. Note that we don't trust the TPM RNG very much, hence do not actually credit
          * any entropy. */
 
+        if (access(TPM2_CREDIT_RANDOM_FLAG_PATH, F_OK) < 0) {
+                if (errno != ENOENT)
+                        log_debug_errno(errno, "Failed to detect if '" TPM2_CREDIT_RANDOM_FLAG_PATH "' exists, ignoring: %m");
+        } else {
+                log_debug("Not adding TPM2 entropy to the kernel random pool again.");
+                return 0; /* Already done */
+        }
+
+        t = now(CLOCK_MONOTONIC);
+
         for (rps = random_pool_size(); rps > 0;) {
                 _cleanup_(Esys_Freep) TPM2B_DIGEST *buffer = NULL;
 
@@ -255,7 +268,7 @@ static int tpm2_credit_random(ESYS_CONTEXT *c) {
                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                                "Zero-sized entropy returned from TPM.");
 
-                r = random_write_entropy(-1, buffer->buffer, buffer->size, false);
+                r = random_write_entropy(-1, buffer->buffer, buffer->size, /* credit= */ false);
                 if (r < 0)
                         return log_error_errno(r, "Failed wo write entropy to kernel: %m");
 
@@ -263,7 +276,12 @@ static int tpm2_credit_random(ESYS_CONTEXT *c) {
                 rps = LESS_BY(rps, buffer->size);
         }
 
-        log_debug("Added %zu bytes of entropy to the kernel random pool.", done);
+        log_debug("Added %zu bytes of TPM2 entropy to the kernel random pool in %s.", done, FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - t, 0));
+
+        r = touch(TPM2_CREDIT_RANDOM_FLAG_PATH);
+        if (r < 0)
+                log_debug_errno(r, "Failed to touch '" TPM2_CREDIT_RANDOM_FLAG_PATH "', ignoring: %m");
+
         return 0;
 }