tpm2_get_random() reads the size of the returned random bytes with the
"w" format of unpack_byte_string(), which stores a u16, but data_size
is a u32. Only its lower half is written, so its upper half keeps
whatever was on the stack, and the "data_size > this_bytes" check
fails with TPM_LIB_ERROR whenever that is not zero.

On qemu-riscv64_smode with a swtpm TPM, this breaks the kaslr-seed
fixup on every bootefi:

  tpm-rng tpm-rng: dm_rng_read failed: -1

Under gdb, data_size was 0xffffffff before the call and 0xffff0008
after it, for an 8-byte request. Whether it fails depends on the stack
contents, so unrelated changes can hide it.

The size field of a TPM2B is a UINT16, so declare data_size as u16.

Fixes: 06bea4980980 ("tpm: add TPM2_GetRandom command support")
Signed-off-by: Hung-Chun Tseng <[email protected]>
---
 lib/tpm-v2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index f443b738f..4c7dfc556 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -977,7 +977,7 @@ u32 tpm2_get_random(struct udevice *dev, void *data, u32 
count)
        const size_t data_size_offset = 10;
        const size_t data_offset = 12;
        size_t response_length = sizeof(response);
-       u32 data_size;
+       u16 data_size;
        u8 *out = data;
 
        while (count > 0) {
-- 
2.43.0

Reply via email to