Commit 1b6d7f9e authored by James Bottomley's avatar James Bottomley Committed by Jarkko Sakkinen

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: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
Reviewed-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
Tested-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
parent 6519fea6
...@@ -292,25 +292,35 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) ...@@ -292,25 +292,35 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
if (!num_bytes || max > TPM_MAX_RNG_DATA) if (!num_bytes || max > TPM_MAX_RNG_DATA)
return -EINVAL; return -EINVAL;
err = tpm_buf_init(&buf, 0, 0); err = tpm2_start_auth_session(chip);
if (err) if (err)
return err; return err;
err = tpm_buf_init(&buf, 0, 0);
if (err) {
tpm2_end_auth_session(chip);
return err;
}
do { do {
tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM); tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM);
tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT
| TPM2_SA_CONTINUE_SESSION,
NULL, 0);
tpm_buf_append_u16(&buf, num_bytes); tpm_buf_append_u16(&buf, num_bytes);
tpm_buf_fill_hmac_session(chip, &buf);
err = tpm_transmit_cmd(chip, &buf, err = tpm_transmit_cmd(chip, &buf,
offsetof(struct tpm2_get_random_out, offsetof(struct tpm2_get_random_out,
buffer), buffer),
"attempting get random"); "attempting get random");
err = tpm_buf_check_hmac_response(chip, &buf, err);
if (err) { if (err) {
if (err > 0) if (err > 0)
err = -EIO; err = -EIO;
goto out; goto out;
} }
out = (struct tpm2_get_random_out *) out = (struct tpm2_get_random_out *)tpm_buf_parameters(&buf);
&buf.data[TPM_HEADER_SIZE];
recd = min_t(u32, be16_to_cpu(out->size), num_bytes); recd = min_t(u32, be16_to_cpu(out->size), num_bytes);
if (tpm_buf_length(&buf) < if (tpm_buf_length(&buf) <
TPM_HEADER_SIZE + TPM_HEADER_SIZE +
...@@ -327,9 +337,12 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max) ...@@ -327,9 +337,12 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
} while (retries-- && total < max); } while (retries-- && total < max);
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
tpm2_end_auth_session(chip);
return total ? total : -EIO; return total ? total : -EIO;
out: out:
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
tpm2_end_auth_session(chip);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment