git: 914892d374e9 - main - tpm20: Preserve all harvested random bytes

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Fri, 30 Oct 2026 22:30:23 UTC
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=914892d374e924cae2a0a1d7a669f246a845ad35

commit 914892d374e924cae2a0a1d7a669f246a845ad35
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-28 00:32:33 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-10-30 22:29:45 +0000

    tpm20: Preserve all harvested random bytes
    
    The TPM requests 16 random bytes every ten seconds, but a random
    harvest event retains at most eight bytes.  random_harvest_queue()
    reduces a larger input to one 32-bit Jenkins hash, so each successful
    TPM request contributed only four bytes to the entropy accumulator.
    
    Split the response into harvest event sized chunks.  This preserves all
    16 random bytes without increasing the TPM command rate or changing its
    high quality source classification.
    
    MFC after:      2 weeks
    Sponsored by:   BBOX.io
    Differential Revision:  https://reviews.freebsd.org/D59246
---
 sys/dev/tpm/tpm20.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/sys/dev/tpm/tpm20.c b/sys/dev/tpm/tpm20.c
index 6c96f1ce848d..b5d40eeac7d7 100644
--- a/sys/dev/tpm/tpm20.c
+++ b/sys/dev/tpm/tpm20.c
@@ -32,6 +32,10 @@
 
 #include "tpm20.h"
 
+#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM
+#include <dev/random/random_harvestq.h>
+#endif
+
 #define TPM_HARVEST_SIZE     16
 
 #define	TPM2_ST_NO_SESSIONS	0x8001
@@ -57,6 +61,7 @@ MALLOC_DEFINE(M_TPM20, "tpm_buffer", "buffer for tpm 2.0 driver");
 
 #if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM
 static void tpm20_harvest(void *arg, int unused);
+static void tpm20_harvest_enqueue(const uint8_t *, size_t);
 #endif
 static int  tpm20_command(device_t, uint32_t, uint16_t, uint32_t,
     const char *);
@@ -388,6 +393,23 @@ tpm20_shutdown(device_t dev)
 }
 
 #if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM
+static void
+tpm20_harvest_enqueue(const uint8_t *entropy, size_t entropy_size)
+{
+	size_t chunk_size;
+
+	/* Preserve all RNG bytes rather than squashing an oversized event. */
+	chunk_size = sizeof(((struct harvest_event *)0)->he_entropy);
+	while (entropy_size != 0) {
+		size_t size;
+
+		size = MIN(entropy_size, chunk_size);
+		random_harvest_queue(entropy, (u_int)size, RANDOM_PURE_TPM);
+		entropy += size;
+		entropy_size -= size;
+	}
+}
+
 /*
  * Get TPM_HARVEST_SIZE random bytes and add them
  * into system entropy pool.
@@ -434,7 +456,7 @@ tpm20_harvest(void *arg, int unused)
 
 	sx_xunlock(&sc->dev_lock);
 	if (entropy_size > 0)
-		random_harvest_queue(entropy, entropy_size, RANDOM_PURE_TPM);
+		tpm20_harvest_enqueue(entropy, entropy_size);
 }
 #endif	/* TPM_HARVEST */