Skip to content

Commit 1b6d7f9

Browse files
jejbjarkkojs
authored andcommitted
tpm: add session encryption protection to tpm2_get_random()
If some entity is snooping the TPM bus, they can see the random numbers we're extracting from the TPM and do prediction attacks against their consumers. Foil this attack by using response encryption to prevent the attacker from seeing the random sequence. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Tested-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
1 parent 6519fea commit 1b6d7f9

1 file changed

Lines changed: 17 additions & 4 deletions

File tree

drivers/char/tpm/tpm2-cmd.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,25 +292,35 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
292292
if (!num_bytes || max > TPM_MAX_RNG_DATA)
293293
return -EINVAL;
294294

295-
err = tpm_buf_init(&buf, 0, 0);
295+
err = tpm2_start_auth_session(chip);
296296
if (err)
297297
return err;
298298

299+
err = tpm_buf_init(&buf, 0, 0);
300+
if (err) {
301+
tpm2_end_auth_session(chip);
302+
return err;
303+
}
304+
299305
do {
300-
tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM);
306+
tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM);
307+
tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT
308+
| TPM2_SA_CONTINUE_SESSION,
309+
NULL, 0);
301310
tpm_buf_append_u16(&buf, num_bytes);
311+
tpm_buf_fill_hmac_session(chip, &buf);
302312
err = tpm_transmit_cmd(chip, &buf,
303313
offsetof(struct tpm2_get_random_out,
304314
buffer),
305315
"attempting get random");
316+
err = tpm_buf_check_hmac_response(chip, &buf, err);
306317
if (err) {
307318
if (err > 0)
308319
err = -EIO;
309320
goto out;
310321
}
311322

312-
out = (struct tpm2_get_random_out *)
313-
&buf.data[TPM_HEADER_SIZE];
323+
out = (struct tpm2_get_random_out *)tpm_buf_parameters(&buf);
314324
recd = min_t(u32, be16_to_cpu(out->size), num_bytes);
315325
if (tpm_buf_length(&buf) <
316326
TPM_HEADER_SIZE +
@@ -327,9 +337,12 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
327337
} while (retries-- && total < max);
328338

329339
tpm_buf_destroy(&buf);
340+
tpm2_end_auth_session(chip);
341+
330342
return total ? total : -EIO;
331343
out:
332344
tpm_buf_destroy(&buf);
345+
tpm2_end_auth_session(chip);
333346
return err;
334347
}
335348

0 commit comments

Comments
 (0)