On Tue Feb 13, 2024 at 7:13 PM EET, James Bottomley wrote:
> 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 <[email protected]>
> Reviewed-by: Jarkko Sakkinen <[email protected]>
>
> ---
> v7: add review
> ---
>  drivers/char/tpm/tpm2-cmd.c | 21 +++++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index a53a843294ed..0cdf892ec2a7 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -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)
>               return -EINVAL;
>  
> -     err = tpm_buf_init(&buf, 0, 0);
> +     err = tpm2_start_auth_session(chip);
>       if (err)
>               return err;
>  
> +     err = tpm_buf_init(&buf, 0, 0);
> +     if (err) {
> +             tpm2_end_auth_session(chip);
> +             return err;
> +     }
> +
>       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_fill_hmac_session(chip, &buf);
>               err = tpm_transmit_cmd(chip, &buf,
>                                      offsetof(struct tpm2_get_random_out,
>                                               buffer),
>                                      "attempting get random");
> +             err = tpm_buf_check_hmac_response(chip, &buf, err);
>               if (err) {
>                       if (err > 0)
>                               err = -EIO;
>                       goto out;
>               }
>  
> -             out = (struct tpm2_get_random_out *)
> -                     &buf.data[TPM_HEADER_SIZE];
> +             out = (struct tpm2_get_random_out *)tpm_buf_parameters(&buf);
>               recd = min_t(u32, be16_to_cpu(out->size), num_bytes);
>               if (tpm_buf_length(&buf) <
>                   TPM_HEADER_SIZE +
> @@ -327,9 +337,12 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, 
> size_t max)
>       } while (retries-- && total < max);
>  
>       tpm_buf_destroy(&buf);
> +     tpm2_end_auth_session(chip);
> +
>       return total ? total : -EIO;
>  out:
>       tpm_buf_destroy(&buf);
> +     tpm2_end_auth_session(chip);
>       return err;
>  }
>  

ditto

BR, Jarkko

Reply via email to